#include "dataprovider.h"
#include <unistd.h>

#define MAX_IGNOR_BAD 3
#define MMM_VOLTAGE   7150     //7150  10.3          10.2
#define MIN_VOLTAGE   12200    //12200 10.5          10.3
#define MAX_VOLTAGE   52000    //62000 12.1  0xe6dc  12.3



#define AVERAGE_BAT   120

DataProvider::DataProvider()
{
    this->fd = ::open("/dev/fusion_dev",O_RDWR);
    this->settings = new QSettings(SETTING_FILE,QSettings::IniFormat);

    print_level          = 3  ;
    dirct_x              = 0  ;
    dirct_y              = 0  ;
    burst_points         = 24 ;
    bob_allow            = 5  ;
    max_allow_change     = 32 ;
    nProgParamSel        = 0  ;

    FiberDiameterMaxDiff = 8  ;
    FiberMaxAngle        = 30 ;
    FiberRoughPoints     = 80 ;

    ov_id                = 0  ;
    meltState            = Idle;
    fusion_max_align     = 500;
    fusion_max_diam_diff = 3  ;
    fusion_max_core_diff = 5  ;
    edge_rough_offset    = 10 ;
    battery_incharge     = 0  ;
    battery_cnt_accum    = 0  ;
    battery_grd_accum    = 0  ;
    battery_grad         = 4  ;

    FiberGap             = 10 ;
    FiberAccuratePoints  = 24 ;
    FiberBlcakLevel      = 100;
    my_cmosStartOver = false;
    my_cmosMessageEn = false;
    my_cmosCount = 0; //test
    my_poweroffCount = 0;

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(RECORD_FILE);
    if (!db.open())
    {
        qDebug("Data Base can not be open!!");
    }

    QSqlQuery query(db);
    QStringList tables = db.tables();
    if (!tables.contains("fusion_record")){
        query.exec("create table fusion_record(id INTEGER PRIMARY KEY autoincrement,type nvarchar(8),loss int,optime nvarchar(40))");
    }
    if (!tables.contains("fusion_lock")){
        query.exec("create table fusion_lock(id INTEGER PRIMARY KEY autoincrement,unlock int)");
    }

    camera0_write_i2c(0x0087, 0x02);
    camera1_write_i2c(0x0087, 0x02);
}

void DataProvider::IncPrintLevel()
{
    if(print_level < 10){
        print_level ++;
        qDebug("print level set to %d",print_level);
    }
}

void DataProvider::DecPrintLevel()
{
    if(print_level > 0){
        print_level --;
        qDebug("print level set to %d",print_level);
    }
}

unsigned int DataProvider::getPrintLevel()
{
    return print_level;
}

void DataProvider::setIniItem(char * ItemName ,int ItemVal)
{
    if( QString( ItemName) == "BackLight")
    {
        SetFusionReg(rBACKLIGHT, ItemVal);
    }

    settings->setValue(ItemName,ItemVal);
    settings->sync();
}

int  DataProvider::getIniItemVal(char * ItemName)
{   
    return settings->value(ItemName).toInt();
}
bool DataProvider::HaskeyExis(QString key)
{
    return settings->allKeys().contains(key);
}

QString  DataProvider::getItems(QString ItemName)
{
    return settings->value(ItemName).toString();
}


void DataProvider::SetFusionReg(unsigned int reg_num,unsigned int reg_val)
{
#ifndef DESK_TOP_RUN
    s_FusionReg freg;

    freg.reg_num    = reg_num;
    freg.reg_setval = reg_val;
    ::ioctl(fd,SET_FUSION_REGS,&freg);
#endif
}

unsigned int DataProvider::GetFusionReg(unsigned int reg_num)
{
#ifndef DESK_TOP_RUN
    s_FusionReg freg;

    freg.reg_num    = reg_num;
    return ::ioctl(fd,GET_FUSION_REGS,&freg);
#else
    if(reg_num == rHEAT_CTRL) return 0x80000000;
    return 0;
#endif
}

void DataProvider::GetFusionMem(unsigned int mem_offset,unsigned int mem_size,unsigned int* mem_buf)
{
    s_FusionReg freg;

    freg.reg_num    = mem_offset;
    freg.readsize   = mem_size;
    freg.readdata   = mem_buf;

    ::ioctl(fd,GET_FUSION_MEMS,&freg);
}

void DataProvider::ManulFandian(unsigned int TimeVal, unsigned int ForceVal){

    SetFusionReg(rGAOYA_FRORCE,ForceVal);
    SetFusionReg(rGAOYA_TIME,TimeVal*1000*100);

    while(GetFusionReg(rGAOYA_TIME) > 0);
    return;
}

char DataProvider::rtc_read_byte(unsigned int addr) {

    unsigned int nTempVal = 0;
    unsigned int nReadVal;

    nTempVal = (0x1 << 31 | 0x1 << 24 | addr << 8 | 0x0);
    SetFusionReg(rRTC_CTRL,nTempVal);
    while (nTempVal & (0x1 << 31)) {
        nTempVal = GetFusionReg(rRTC_CTRL);
    }

    nTempVal = GetFusionReg(rRTC_READ);
    nReadVal = nTempVal & 0xff;
    usleep(10000);

    return nReadVal;
}

void DataProvider::rtc_write_byte(unsigned int addr, unsigned int data) {
    unsigned int nTempVal = 0;

    nTempVal = (0x1 << 31 | addr << 8 | data);
    SetFusionReg(rRTC_CTRL,nTempVal);
    while (nTempVal & (0x1 << 31)) {
        nTempVal = GetFusionReg(rRTC_CTRL);
    }
    usleep(10000);
}

void DataProvider::set_rtc_remote_time(unsigned int Timestamp[6]) {

    rtc_write_byte(8, Timestamp[0]); // rBCDYEAR
    rtc_write_byte(7, Timestamp[1]); // rBCDMON
    rtc_write_byte(5, Timestamp[2]); // rBCDDAY
    rtc_write_byte(4, Timestamp[3]); // rBCDHOUR
    rtc_write_byte(3, Timestamp[4]); // rBCDMIN
    rtc_write_byte(2, Timestamp[5]); // rBCDSEC

    qDebug("Current BCD Time set to: %x-%x-%x  %x:%x:%x",Timestamp[0],Timestamp[1],Timestamp[2],Timestamp[3],Timestamp[4],Timestamp[5]);
}

void DataProvider::get_rtc_remote_time(unsigned int Timestamp[6]) {

    Timestamp[0] = rtc_read_byte(8);
    Timestamp[1] = rtc_read_byte(7);
    Timestamp[2] = rtc_read_byte(5);
    Timestamp[3] = rtc_read_byte(4);
    Timestamp[4] = rtc_read_byte(3);
    Timestamp[5] = rtc_read_byte(2);

    Timestamp[0] &= 0xff;
    Timestamp[1] &= 0x1f;
    Timestamp[2] &= 0x3f;
    Timestamp[3] &= 0x3f;
    Timestamp[4] &= 0x7f;
    Timestamp[5] &= 0x7f;

    printf(" *******  timestamp: 20%2x-%2x-%2x  %x:%x:%x .\n", Timestamp[0],Timestamp[1], Timestamp[2], Timestamp[3], Timestamp[4], Timestamp[5]);
}

void DataProvider::setCurrentTime(QDateTime dataTime)
{
    unsigned int Ts[6];
    unsigned int Temp;
    QDate    dt;
    QTime    tm;

    time_t tt = (time_t)dataTime.toTime_t();    
    stime(&tt);

    dt = dataTime.date();
    tm = dataTime.time();

    Temp  = ((dt.year() < 3000)&&(dt.year() > 2016))?(dt.year()- 2000):17;

    Ts[0] = Temp;
    Ts[1] = dt.month();
    Ts[2] = dt.day();
    Ts[3] = tm.hour();
    Ts[4] = tm.minute();
    Ts[5] = tm.second();

    Ts[0] = (Ts[0]/10)*16 + (Ts[0]%10);
    Ts[1] = (Ts[1]/10)*16 + (Ts[1]%10);
    Ts[2] = (Ts[2]/10)*16 + (Ts[2]%10);
    Ts[3] = (Ts[3]/10)*16 + (Ts[3]%10);
    Ts[4] = (Ts[4]/10)*16 + (Ts[4]%10);
    Ts[5] = (Ts[5]/10)*16 + (Ts[5]%10);

    set_rtc_remote_time(Ts);
    get_rtc_remote_time(Ts);
}

QDateTime DataProvider::getCurrentTime()
{
    return QDateTime::currentDateTime();
}

void DataProvider::InitSystemTime()
{
    unsigned int Ts[6];
    QString strBuffer;
    QDateTime dataTime;

    get_rtc_remote_time(Ts);

    strBuffer.sprintf("%x-%x-%x %x:%x:%x",(0x2000+Ts[0]),Ts[1],Ts[2],Ts[3],Ts[4],Ts[5]);
    dataTime = QDateTime::fromString(strBuffer, "yyyy-M-d h:m:s");

    time_t tt = (time_t)dataTime.toTime_t();
    stime(&tt);
}

void DataProvider::SysCheckProc()
{

}

void DataProvider::GetJointInfo(int info[30])
{
    for(int nI=0;nI < 30;nI++)
    {
        info[nI] = joint_info[nI];
    }
}

MeltState DataProvider::getMeltState()
{
    return meltState;
}

void DataProvider::AddDbSpliceRecord()
{

    QDateTime dtmie = QDateTime::currentDateTime();
    QString   dStr;
    QString   tmp;
    QSqlQuery query(db);
    int       ValTemp;
    int t_dischargeCount;

    SetFusionReg(rBEEP_TONE,113600);     //440hz beep
    SetFusionReg(rBEEP_ON  ,8*1000*10000);

    query.exec("select count(*) from fusion_record");

    int row;
    while(query.next()){
        row = query.value(0).toInt() ;
    }

    //qDebug() << "row::" << row <<__FILE__<<__LINE__;

    if(row > 7999){ // limit to 1000 records
        row = 0;
    }
    else{
        row++;
    }

    tmp.setNum(row);
    dStr.append("insert into fusion_record values(");
    dStr.append(tmp);
    dStr.append(",'SM',");
    tmp.setNum(estimatedLoss);
    dStr.append(tmp);
    dStr.append(",'");
    dStr.append(dtmie.toString("yyyy-MM-dd hh:mm:ss"));


    dStr.append("')");
    query.exec(dStr);
   // qDebug("%s",qPrintable(dStr));

    if(estimatedLoss < 100 ){
        ValTemp = getIniItemVal("SuccessNum");
        ValTemp++;
        t_dischargeCount++;
        setIniItem("SuccessNum",ValTemp);
    }
    else {
        ValTemp = getIniItemVal("FailNum");
        ValTemp++;
        t_dischargeCount++;
        setIniItem("FailNum",ValTemp);
    }
    setIniItem("DischargeNum",ValTemp);
}

QString DataProvider::getMeltStateStr()
{
    QString rtn;

    switch(meltState)
    {
        case MeltDebug:
            rtn = melt_Debug;//工程模式
            break;
         case MeltPwrDown:
            rtn = melt_PwrDown;//保存设置
            break;
        case MeltInit:
        case MeltReset:
            rtn = melt_Init;//初始化
            break;
        case MeltQuickPush:
            rtn = melt_QuickPush;//快速推进

            break;
        case MeltClean:
            rtn = "清洁放电";
            screenshotState("MeltClean",false);
            break;
        case MeltSlowPush:
            rtn = melt_SlowPush;//精准推进
            break;
        case MeltRoughAlign:
            rtn = "快速对芯";
            break;
        case MeltBaseErr:
            rtn = "状态报告";
            break;
        case MeltPreciseAlign:
            rtn = melt_PreciseAlign;//精准对芯
            break;
        case MeltPause:
        case MeltAlignDetial:
            rtn = melt_Pause;//暂停
            screenshotState("MeltAlignDetial",false);
            break;
        case MeltProc:
            rtn = melt_Proc;//放电熔接

            break;
        case TestSave:
            rtn = melt_Save;//保存测试结果
            break;
        case MeltAgain:
            usleep(2000000);
        case MeltTention:
            usleep(1000000);
            break;
        case MeltDone :
            usleep(500000);
            joint_process_x();
            joint_process_y();
            getEstimatedLoss();

            if(estimatedLoss == 0)
            {

                rtn = melt_estimatedLoss+" [0.00";//估算损耗
                 screenshotState("0.0",true,1);
            }
            else if(estimatedLoss < 10)
            {
                if( estimatedLoss == 9 )
                {
                   melt_estimatedLoss = 8;
                }
                rtn = melt_estimatedLoss+" [0.0";//估算损耗
                QString t1;
                t1.setNum(estimatedLoss%5);
                rtn.append(t1);
                screenshotState("0.0" +t1,true,1);
            }
            else if(estimatedLoss < 100)
            {
                rtn = melt_estimatedLoss+" [0.0";//估算损耗
                QString t2;
                t2.setNum(estimatedLoss%10);
                rtn.append(t2);
                screenshotState("0.0" + t2,true,1);
            }
            else
            {
                screenshotState("MeltFail",true, 0);
                rtn = melt_failure +" [0.";//熔接失败
                QString t3;
                t3.setNum(estimatedLoss%100);
                rtn.append(t3);
            }
            rtn.append(" db]");
            break;          
        case MeltFiberError:
            rtn = melt_Error;//端面报告
            screenshotState("MeltFiberError",false);
            break;
        default:
            rtn = melt_free;//空闲
            break;
    }

    return rtn;

}

void DataProvider::applyDischargingSuggestion(unsigned int suggest[2])
{
    /*
    unsigned int no_cable_cnt, y_start, y_end;
    unsigned int nA,nB,nJ;

    Get_FiberYEdge(0);

    y_end = y_start = 0;
    no_cable_cnt = 0;
    for (nJ = 64; nJ < 192; nJ++) {
        if (fibery_info[nJ] == 0) {
            no_cable_cnt++;
            y_end = nJ;
        }
        if (no_cable_cnt == 1)
            y_start = nJ;
    }
    nA = getIniItemVal("YBasePosition");
    if(nA == 0) nA = 320;
    nA = nA - 320;
    if(abs(nA) > 0x6D) nA = 0;

    qDebug("y_start = %8d y_end= %8d", 192 + y_start, 192 + y_end);
    nB = 192 + ((y_start + y_end)/2) + nA;
    setIniItem("YBasePosition",          nB );
    */

    if(nProgParamSel == 0) {
        setIniItem("SingleMeltIntense",      IntenseSuggested  );
        setIniItem("SinglePreMeltIntense",   PreIntenseSuggested );
    }
    else {
        setIniItem("MultiMeltIntense",       IntenseSuggested  );
        setIniItem("MultiPreMeltIntense",    PreIntenseSuggested );
    }

    setIniItem("MeltPosition",           PositionSuggested );
    suggest[0] = PreIntenseSuggested;
    suggest[1] = IntenseSuggested;
    qDebug("ParamSel=%d apply:: MeltIntense=%d PreMeltPosition=%d MeltPosition=%d",nProgParamSel,IntenseSuggested,PreIntenseSuggested,PositionSuggested);

    AdjustNewYPostion();

}

void DataProvider::AdjustNewYPostion()
{
    int adjusty_edge = GetFusionReg(rCALIB_EDG1);
    int gap0 = adjusty_edge&0xffff;
    int gap1 = (adjusty_edge&0xffff0000) >> 16;

    int mpoints = PositionSuggested - (gap0 + gap1)/2;

    int y_aoffset = getIniItemVal("YBasePosition");
    if (abs(y_aoffset + mpoints) < 100 ) y_aoffset = y_aoffset + mpoints;

    qDebug("Auto Cliberation::YBasePosition decreased to %d",y_aoffset);
    setIniItem("YBasePosition",y_aoffset);
    OV5640_XOFFSET(1,3*y_aoffset);
}

MeltMode DataProvider::getMeltMode()
{
    meltMode = (MeltMode)(settings->value("MeltMode").toInt());
    return meltMode;
}

HeatingMode DataProvider::getHeatingMode()
{
    heatingMode = (HeatingMode)(settings->value("HeatingMode").toInt());
    return heatingMode;
}

SpeedMode DataProvider::getSpeedMode()
{
    spdMode = (SpeedMode)(settings->value("SpeedMode").toInt());
    return spdMode;
}

void DataProvider::SetPwrOff(unsigned int t)
{
    pwroff_t = t;
}

void DataProvider::pwroff()
{
    unsigned int ValTemp;
//    SetFusionReg(rBEEP_TONE,213600);        //440hz beep
//    SetFusionReg(rBEEP_ON  ,12*1000*10000); //3s
//    SetFusionReg(rBEEP_TONE,113600);     //440hz beep
//    usleep(5000000);

    ValTemp  = GetFusionReg(rSD_WP); //set power off
    ValTemp |= (0x1 << 1);
    SetFusionReg(rSD_WP,ValTemp);
}


void DataProvider::updatePwroff()
{
    unsigned int ValTemp;
    ValTemp  = GetFusionReg(rTOUCH_STATUS);
    if( (ValTemp&0x80000000) != 0)
    {
        emit powerOff(0);
        SetFusionReg(rBEEP_TONE,213600);        //440hz beep
        SetFusionReg(rBEEP_ON  ,12*1000*10000); //3s
        SetFusionReg(rBEEP_TONE,113600);     //440hz beep
    }
}


void DataProvider::SetStandBy(unsigned int t)
{
    standby_t = t;
}

int  DataProvider::GetPwrOff()
{
    return (pwroff_t + 1)*60/**1000*/;
}

int  DataProvider::GetStandBy()
{
    return (standby_t + 1)*60*1000;
}

void DataProvider::setMeltMode(MeltMode m)
{
    settings->setValue("MeltMode",(int)m);
    settings->sync();
    meltMode=m;
}

void DataProvider::setHeatingMode(HeatingMode hMode)
{
    settings->setValue("HeatingMode",(int)hMode);
    settings->sync();
    heatingMode = hMode;
}

void DataProvider::setSpeedMode(SpeedMode spdMode)
{
    settings->setValue("SpeedMode",(int)spdMode);
    settings->sync();
    this->spdMode = spdMode;
}


//! 刷新该类的语言 lbs-2017/4/26
void DataProvider::setLanguageTr(QStringList strTrList)
{
    if( strTrList.length() >=  25 ){
        melt_Debug = strTrList[0];
        melt_PwrDown = strTrList[1];
        melt_Init = strTrList[2];
        melt_QuickPush = strTrList[3];
        melt_SlowPush = strTrList[4];
        melt_PreciseAlign = strTrList[5];
        melt_Pause = strTrList[6];
        melt_Proc = strTrList[7];
        melt_Save = strTrList[8];
        melt_estimatedLoss = strTrList[9];
        melt_failure = strTrList[10];
        melt_Tention = strTrList[11];
        melt_Report = strTrList[12];
        melt_Error = strTrList[13];
        melt_free = strTrList[14];

        mode_Auto = strTrList[15];
        mode_Manual = strTrList[16];
        mode_Pause1 = strTrList[17];
        mode_Pause2 = strTrList[18];
        mode_Pause3 = strTrList[19];
        mode_Calibe = strTrList[20];

        spd_fast = strTrList[21];
        spd_precise = strTrList[22];

        Heating_Auto = strTrList[23];
        Heating_Manual = strTrList[24];
    }


}

QString DataProvider::getMeltModeStr()
{
    QString rtn;
    if(meltMode==Auto)
        rtn = mode_Auto;//自动熔接模式
    else if(meltMode==Manual)
        rtn = mode_Manual;//手动熔接模式
    else if(meltMode==Pause1)
        rtn = mode_Pause3;//推纤暂停模式    这里顺序反了
    else if(meltMode==Pause2)
        rtn = mode_Pause2;//对准暂停模式
    else if(meltMode==Pause3)
        rtn = mode_Pause1;//连续暂停模式
    else if(meltMode==Calibe)
        rtn = mode_Calibe;//放电校准模式

    return rtn;
}

QString DataProvider::getSpeedModeStr()
{
    QString rtn;
    if(spdMode==Fast)
        rtn =  spd_fast;//极速模式
    else if(spdMode==Precise)
        rtn = spd_precise;//精准模式
    return rtn;
}

QString DataProvider::getHeatingModeStr()
{
    QString rtn;


    if(getHeatingMode()==AutoHeating)
        rtn = Heating_Auto;//自动加热模式
    else if(getHeatingMode()==ManualHeating)
        rtn = Heating_Manual;//手动加热模式
    return rtn;
}

bool DataProvider::getVLight()
{
    light = (Light)(settings->value("Light").toInt());
    return (bool)light;
}
void DataProvider::setVLight(bool on)
{
    settings->setValue("Light",(int)on);
    light = (Light)on;
}


void DataProvider::setMeltState(MeltState ms)
{
    meltState = ms;
    emit updateMeltState();
}

void DataProvider::UIChange(int id){
    emit updateDynamicUI(id);
}

int DataProvider::getEstimatedLoss()
{ 
    volatile unsigned int nLoss;

    /*
    QTime current_time = QTime::currentTime();
    int second = current_time.second();
    */

    /*
    X:
    joint_info[6]  = face_l;
    joint_info[7]  = face_r;
    joint_info[21] = diameter;
    joint_info[22] = core;
    joint_info[23] = bob_point;
    Y:
    joint_info[16] = face_l;
    joint_info[17] = face_r;
    joint_info[26] = diameter;
    joint_info[27] = core;
    joint_info[28] = bob_point;
    */

    nLoss = (joint_info[6] + joint_info[16] + joint_info[7] + joint_info[17] );

    if(nLoss < 24) estimatedLoss = 0;
    else {
        estimatedLoss = (nLoss - 24)/4;
    }

    nLoss = (joint_info[27] + joint_info[22]);
    if(nLoss > 0){
        estimatedLoss  += 5;
    }

    nLoss = (joint_info[21] + joint_info[26]);
    if(nLoss > 5) {
        estimatedLoss += 5;
    }
    else {
        estimatedLoss += nLoss;
    }

    nLoss = (joint_info[23] + joint_info[28])/2;
    if(nLoss > 5) {
        estimatedLoss += 5;
    }
    else {
        estimatedLoss += nLoss;
    }

    if(((joint_info[25]&0x4) == 0x4)||((joint_info[20]&0x4) == 0x4)) estimatedLoss += 50;
    else if(((joint_info[25]&0x2) == 0x2)||((joint_info[20]&0x2) == 0x2)) estimatedLoss += 100;
    else if(((joint_info[25]&0x1) == 0x1)||((joint_info[20]&0x1) == 0x1)) estimatedLoss += 200;
    qDebug("result_x=0x%x result_y=0x%x diameter=%d core=%d bob_point=%d",joint_info[20],joint_info[25],joint_info[21],joint_info[22],joint_info[23]);

    return estimatedLoss;
}

int DataProvider::getUnlockKey(){
    int unlock_key;

    QSqlQuery query(db);
    query.exec("SELECT * FROM fusion_lock"); // 查询的结果可能不止一条记录，所以我们称之为结果集

    while(!query.next()) {
        unlock_key = query.value(1).toInt();
        qDebug("unlock_key is %x",unlock_key);
        break;
    }

    if (unlock_key == 0) return 0;
    else return 1;
}
//
void DataProvider::cleanRecords()
{
    QSqlQuery query(db);
    query.exec("DELETE FROM fusion_record");

    QSqlQueryModel *model = new QSqlQueryModel;
    model->setQuery("DELETE from fusion_record");

    //lbs 2017/7/20
    setIniItem("SuccessNum",0);
    setIniItem("FailNum",0);

}

//
void DataProvider::setRecords(int startP)
{
    int nI,nLoss;

    //取前八个
    QStringList tmpRecord;
    QSqlQuery query(db);

    query.exec("SELECT * FROM fusion_record"); // 查询的结果可能不止一条记录，所以我们称之为结果集
    if(query.last()){
        QString msg;
        msg.append("(new) ");
        msg.append(query.value(1).toString());
        if((query.value(2).toInt()) > 99){
            msg.append("/FAIL");
        }
        else if((query.value(2).toInt()) > 10){
            msg.append("/0.0");
            nLoss = query.value(2).toInt();

            QString t1;
            t1.setNum(nLoss%10);
            msg.append(t1);
        }
        else if((query.value(2).toInt()) > 0){
            msg.append("/0.0");
            nLoss = query.value(2).toInt();

            QString t1;
            t1.setNum(nLoss%5);
            msg.append(t1);
        }
        else {
            msg.append("/0.00");
        }
        msg.append("/");
        msg.append(query.value(3).toString());

        tmpRecord.append(msg);
    }
    for(nI=0;nI < startP;nI ++){
        if(!query.previous()) break;
    }
    for(nI=1;nI<9;nI++)
    {
        if(!query.previous()) break;
        QString msg = query.value(1).toString();
        if((query.value(2).toInt()) > 99){
            msg.append("/FAIL");
        }
        else if((query.value(2).toInt()) > 10){
            msg.append("/0.0");
            nLoss = query.value(2).toInt();

            QString t1;
            t1.setNum(nLoss%10);
            msg.append(t1);
        }
        else if((query.value(2).toInt()) > 0){
            msg.append("/0.0");
            nLoss = query.value(2).toInt();

            QString t1;
            t1.setNum(nLoss%5);
            msg.append(t1);
        }
        else {
            msg.append("/0.00");
        }
        msg.append("/");
        msg.append(query.value(3).toString());

        tmpRecord.append(msg);
    }
    for(;nI<9;nI++)tmpRecord.append("  ");

    this->records = tmpRecord;

}

QStringList DataProvider::getRecords(bool ifSucceeded)
{
    return records;
}

//调用显示X屏
void DataProvider::setDisplayX()
{
    SetFusionReg(rCAM0_SCALER,(1<<16)|1);
    SetFusionReg(rCAM1_SCALER,(2<<16)|1);
    usleep(50000);
    SetFusionReg(rVIEW_XY    , 0x1     );
}
//调用显示Y屏
void DataProvider::setDisplayY()
{
    SetFusionReg(rCAM0_SCALER,(2<<16)|1);
    SetFusionReg(rCAM1_SCALER,(1<<16)|1);
    usleep(50000);
    SetFusionReg(rVIEW_XY    , 0x2     );
}
//调用显示XY双屏幕
void DataProvider::setDisplayXY()
{
    SetFusionReg(rCAM0_SCALER,(2<<16)|1);
    SetFusionReg(rCAM1_SCALER,(2<<16)|1);
    usleep(50000);
    SetFusionReg(rVIEW_XY    , 0x0     );
}

//Actions
void DataProvider::camera0_write_i2c(unsigned short addr,unsigned char data){

    SetFusionReg(rSCCB0_CTRCL,0x1 << 31|addr << 8|data);
    while(GetFusionReg(rSCCB0_CTRCL)&(0x1 << 31)){
        usleep(1000);
    }
    usleep(10000);
}

void DataProvider::camera1_write_i2c(unsigned short addr,unsigned char data){

    SetFusionReg(rSCCB1_CTRCL,0x1 << 31|addr << 8|data);
    while(GetFusionReg(rSCCB1_CTRCL)&(0x1 << 31)){
        usleep(1000);
    }
    usleep(10000);
}

//int DataProvider::OV5640_init_setting(void)
//{
//    int i;
//    int regInit[] =
//     {
//         0x3008, 0x42, // software power down
//         0x3103, 0x03, // sysclk from pll
//         0x3017, 0xff, // Frex, Vsync, Href, PCLK, D[9:6] output
//         0x3018, 0xff, // D[5:0], GPIO[1:0] output
//         0x3034, 0x1a, // PLL, MIPI 10-bit
//         0x3037, 0x13, // PLL
//         0x3108, 0x01, // clock divider
//         0x3630, 0x36,
//         0x3631, 0x0e,
//         0x3632, 0xe2,
//         0x3633, 0x12,
//         0x3621, 0xe0,
//         0x3704, 0xa0,
//         0x3703, 0x5a,
//         0x3715, 0x78,
//         0x3717, 0x01,
//         0x370b, 0x60,
//         0x3705, 0x1a,
//         0x3905, 0x02,
//         0x3906, 0x10,
//         0x3901, 0x0a,
//         0x3731, 0x12,
//         0x3600, 0x08, // VCM debug
//         0x3601, 0x33, // VCM debug
//         0x302d, 0x60, // system control
//         0x3620, 0x52,
//         0x371b, 0x20,
//         0x471c, 0x50,
//         0x3a13, 0x43, // pre-gain = 1.05x
//         0x3a18, 0x00, // AEC gain ceiling = 7.75x
//         0x3a19, 0x7c, // AEC gain ceiling
//         0x3635, 0x13,
//         0x3636, 0x03,
//         0x3634, 0x40,
//         0x3622, 0x01,
//         0x3c01, 0x34, // sum auto, band counter enable, threshold = 4
//         0x3c04, 0x28, // threshold low sum
//         0x3c05, 0x98, // threshold high sum
//         0x3c06, 0x00, // light meter 1 threshold H
//         0x3c07, 0x07, // light meter 1 threshold L
//         0x3c08, 0x00, // light meter 2 threshold H
//         0x3c09, 0x1c, // light meter 2 threshold L
//         0x3c0a, 0x9c, // sample number H
//         0x3c0b, 0x40, // sample number L
//         0x3708, 0x64,
//         0x4001, 0x02, // BLC start line
//         0x4005, 0x1a, // BLC always update
//         0x3000, 0x00, // enable MCU, OTP
//         0x3004, 0xff, // enable BIST, MCU memory, MCU, OTP, STROBE, D5060, timing, array clock
//         0x300e, 0x58, // MIPI 2 lane? power down PHY HS TX, PHY LP RX, DVP enable
//         0x302e, 0x00,
//         0x4300, 0x30, // YUV 422, YUYV
//         0x501f, 0x00, // ISP YUV 422
//         0x440e, 0x00,
//         0x5000, 0xa7, // LENC on, raw gamma on, BPC on, WPC on, CIP on
//         0x3a0f, 0x30, // stable in high
//         0x3a10, 0x28, // stable in low
//         0x3a1b, 0x30, // stable out high
//         0x3a1e, 0x26, // stable out low
//         0x3a11, 0x60, // fast zone high
//         0x3a1f, 0x14, // fast zone low
//         0x5800, 0x23,
//         0x5801, 0x14,
//         0x5802, 0x0f,
//         0x5803, 0x0f,
//         0x5804, 0x12,
//         0x5805, 0x26,
//         0x5806, 0x0c,
//         0x5807, 0x08,
//         0x5808, 0x05,
//         0x5809, 0x05,
//         0x580a, 0x08,
//         0x580b, 0x0d,
//         0x580c, 0x08,
//         0x580d, 0x03,
//         0x580e, 0x00,
//         0x580f, 0x00,
//         0x5810, 0x03,
//         0x5811, 0x09,
//         0x5812, 0x07,
//         0x5813, 0x03,
//         0x5814, 0x00,
//         0x5815, 0x01,
//         0x5816, 0x03,
//         0x5817, 0x08,
//         0x5818, 0x0d,
//         0x5819, 0x08,
//         0x581a, 0x05,
//         0x581b, 0x06,
//         0x581c, 0x08,
//         0x581d, 0x0e,
//         0x581e, 0x29,
//         0x581f, 0x17,
//         0x5820, 0x11,
//         0x5821, 0x11,
//         0x5822, 0x15,
//         0x5823, 0x28,
//         0x5824, 0x46,
//         0x5825, 0x26,
//         0x5826, 0x08,
//         0x5827, 0x26,
//         0x5828, 0x64,
//         0x5829, 0x26,
//         0x582a, 0x24,
//         0x582b, 0x22,
//         0x582c, 0x24,
//         0x582d, 0x24,
//         0x582e, 0x06,
//         0x582f, 0x22,
//         0x5830, 0x40,
//         0x5831, 0x42,
//         0x5832, 0x24,
//         0x5833, 0x26,
//         0x5834, 0x24,
//         0x5835, 0x22,
//         0x5836, 0x22,
//         0x5837, 0x26,
//         0x5838, 0x44,
//         0x5839, 0x24,
//         0x583a, 0x26,
//         0x583b, 0x28,
//         0x583c, 0x42,
//         0x583d, 0xce, // LENC BR offset
//         0x5180, 0xff, // AWB B block
//         0x5181, 0xf2, // AWB control
//         0x5182, 0x00, // [7:4] max local counter, [3:0] max fast counter
//         0x5183, 0x14, // AWB advance
//         0x5184, 0x25,
//         0x5185, 0x24,
//         0x5186, 0x09,
//         0x5187, 0x09,
//         0x5188, 0x09,
//         0x5189, 0x75,
//         0x518a, 0x54,
//         0x518b, 0xe0,
//         0x518c, 0xb2,
//         0x518d, 0x42,
//         0x518e, 0x3d,
//         0x518f, 0x56,
//         0x5190, 0x46,
//         0x5191, 0xf8, // AWB top limit
//         0x5192, 0x04, // AWB botton limit
//         0x5193, 0x70, // Red limit
//         0x5194, 0xf0, // Green Limit
//         0x5195, 0xf0, // Blue limit
//         0x5196, 0x03, // AWB control
//         0x5197, 0x01, // local limit
//         0x5198, 0x04,
//         0x5199, 0x12,
//         0x519a, 0x04,
//         0x519b, 0x00,
//         0x519c, 0x06,
//         0x519d, 0x82,
//         0x519e, 0x38, // AWB control
//         0x5480, 0x01, // BIAS plus on
//         0x5481, 0x08,
//         0x5482, 0x14,
//         0x5483, 0x28,
//         0x5484, 0x51,
//         0x5485, 0x65,
//         0x5486, 0x71,
//         0x5487, 0x7d,
//         0x5488, 0x87,
//         0x5489, 0x91,
//         0x548a, 0x9a,
//         0x548b, 0xaa,
//         0x548c, 0xb8,
//         0x548d, 0xcd,
//         0x548e, 0xdd,
//         0x548f, 0xea,
//         0x5490, 0x1d,
//         0x5381, 0x1e, // CMX1 for Y
//         0x5382, 0x5b, // CMX2 for Y
//         0x5383, 0x08, // CMX3 for Y
//         0x5384, 0x0a, // CMX4 for U
//         0x5385, 0x7e, // CMX5 for U
//         0x5386, 0x88, // CMX6 for U
//         0x5387, 0x7c, // CMX7 for V
//         0x5388, 0x6c, // CMX8 for V
//         0x5389, 0x10, // CMX9 for V
//         0x538a, 0x01, // sign[9]
//         0x538b, 0x98, // sign[8:1]
//         0x5580, 0x06, // brightness on, saturation on
//         0x5583, 0x40, // Sat U
//         0x5584, 0x10, // Sat V
//         0x5589, 0x10, // UV adjust th1
//         0x558a, 0x00, // UV adjust th2[8]
//         0x558b, 0xf8, // UV adjust th2[7:0]
//         0x501d, 0x40, // enable manual offset in contrast
//         0x5300, 0x08, // sharpen-MT th1
//         0x5301, 0x30, // sharpen-MT th2
//         0x5302, 0x10, // sharpen-MT off1
//         0x5303, 0x00, // sharpen-MT off2
//         0x5304, 0x08, // De-noise th1
//         0x5305, 0x30, // De-noise th2
//         0x5306, 0x08, // De-noise off1
//         0x5307, 0x16, // De-noise off2
//         0x5309, 0x08, // sharpen-TH th1
//         0x530a, 0x30, // sharpen-TH th2
//         0x530b, 0x04, // sharpen-TH off1
//         0x530c, 0x06, // sharpen-TH off2
//         0x5025, 0x00,
//         0x3008, 0x02, // wake up from software power down
//     };

//    // initialize OV5640
//    camera0_write_i2c(0x3103, 0x11); // sysclk from pad
//    camera0_write_i2c(0x3008, 0x82); // software reset
//    camera1_write_i2c(0x3103, 0x11); // sysclk from pad
//    camera1_write_i2c(0x3008, 0x82); // software reset
//    // delay 5ms
//    usleep(5000);
//    // Write initialization table
//    for (i=0; i<sizeof(regInit)/sizeof(int); i+=2)
//    {
//        camera0_write_i2c(regInit[i], regInit[i+1]);
//        camera1_write_i2c(regInit[i], regInit[i+1]);
//    }
//    return 0;
//}

//void DataProvider::OV5640_vga30fps_config(void) {

//    int i;
//    int regCfgs[] =
//    {
//        0x3035, 0x11, // PLL
//        0x3036, 0x46, // PLL
//        0x3c07, 0x08, // light meter 1 threshold [7:0]
//        0x3820, 0x41, // Sensor flip off, ISP flip on
//        0x3821, 0x07, // Sensor mirror on, ISP mirror on, H binning on
//        //*********************
//        //0x3800, 0x00, // HS
//        //0x3801, 0x00, // HS
//        //0x3804, 0x0a, // HW (HE)
//        //0x3805, 0x3f, // HW (HE)
//        0x3800, 0x01, // HS
//        0x3801, 0x48, // HS
//        0x3804, 0x08, // HW (HE)
//        0x3805, 0xc8, // HW (HE)
//        //*********************
//        0x3802, 0x00, // VS
//        0x3803, 0x04, // VS
//        0x3806, 0x07, // VH (VE)
//        0x3807, 0x9b, // VH (VE)
//        0x3808, 0x02, // DVPHO
//        0x3809, 0x80, // DVPHO
//        0x380a, 0x01, // DVPVO
//        0x380b, 0xe0, // DVPVO
//        0x380c, 0x07, // HTS
//        0x380d, 0x68, // HTS
//        0x380e, 0x03, // VTS
//        0x380f, 0xd8, // VTS
//        0x3810, 0x00, // X offset
//        0x3811, 0x10, // X offset
//        0x3812, 0x00, // Y offset
//        0x3813, 0x06, // Y Timing Voffset
//        0x3814, 0x31, // X INC
//        0x3815, 0x31, // Y INC
//        0x3618, 0x00,
//        0x3612, 0x29,
//        0x3709, 0x52,
//        0x370c, 0x03,
//        0x3a02, 0x17, // 60Hz max exposure, night mode 5fps
//        0x3a03, 0x10, // 60Hz max exposure
//        0x3a14, 0x17, // 50Hz max exposure, night mode 5fps
//        0x3a15, 0x10, // 50Hz max exposure
//        0x4004, 0x02, // BLC 2 lines
//        0x3002, 0x1c, // reset JFIFO, SFIFO, JPEG
//        0x3006, 0xc3, // disable clock of JPEG2x, JPEG
//        0x4713, 0x03, // JPEG mode 3
//        0x4407, 0x04, // Quantization scale
//        0x460b, 0x35,
//        0x460c, 0x22,
//        0x4837, 0x22, // DVP CLK divider
//        0x3824, 0x02, // DVP CLK divider
//        0x5001, 0xa3, // SDE on, scale on, UV average off, color matrix on, AWB on
//        0x302C, 0xc2, // drive capacity:2x

//        //0x503d, 0x82, // TEST PATTERN
//        //0x4741, 0x00,
//    }; // ISP YUV 422a

//    // initialize OV5640
//    for (i=0; i<sizeof(regCfgs)/sizeof(int); i+=2)
//    {
//        camera0_write_i2c(regCfgs[i], regCfgs[i+1]);
//        camera1_write_i2c(regCfgs[i], regCfgs[i+1]);
//    }
//}


void DataProvider::OV5640_XOFFSET(int camera,int offset) // offset
{
    int i;
    int m = 0x148 + offset; // 1920
    int k = 0x8C8 + offset;
    int regCfgs0[] =  {
        0x3800, (m&0xf00)>>8, // X offset
        0x3801, (m&0xff),     // X offset
        0x3804, (k&0xf00)>>8, // X offset
        0x3805, (k&0xff),     // X offset
    };

    if(::abs(offset) > 0x148 ) return;
    //qDebug("baseY is set to %d - %d.",m,k);

    for (i=0; i<sizeof(regCfgs0)/sizeof(int); i+=2)
    {
        if(camera == 0)camera0_write_i2c(regCfgs0[i], regCfgs0[i+1]);
        if(camera == 1)camera1_write_i2c(regCfgs0[i], regCfgs0[i+1]);
    }
}

void DataProvider::OV5640_YOFFSET(int camera,int offset)
{
//    int i;
//    int m = offset + 0x4;
//    int k = offset + 0x79b;
//    int regCfgs0[] =  {
//        0x3802, (m&0x700)>>8, // Y offset
//        0x3803, (m&0xff),     // Y offset
//        0x3806, (k&0x700)>>8, // Y offset
//        0x3807, (k&0xff),     // Y offset
//    };
//    if(::abs(offset) > 0x80 ) return;
//    for (i=0; i<sizeof(regCfgs0)/sizeof(int); i+=2)
//    {
//        if((camera == 0)||(camera > 1)) camera0_write_i2c(regCfgs0[i], regCfgs0[i+1]);
//        if((camera == 1)||(camera > 1)) camera1_write_i2c(regCfgs0[i], regCfgs0[i+1]);
//    }
}


void DataProvider::OV5640_AGC(int agc_on)
{
    int i,ValTemp = 0;
    int regCfgs0[] =  {
        0x350a, 0x00, //
        0x350b, 0x20, // AGC = 0x20
    };
    int regCfgs1[] =  {
        0x350a, 0x00, //
        0x350b, 0x20, // AGC = 0x20
    };

    if(agc_on == 1){
        camera0_write_i2c(0x3503, 0x00);
        camera1_write_i2c(0x3503, 0x00);
        return;
    }
    else {
        camera0_write_i2c(0x3503, 0x03);  // AEC off /AGC off
        camera1_write_i2c(0x3503, 0x03);  // AEC off /AGC off
    }

    ValTemp = getIniItemVal("AGC0");
    if(ValTemp > 0)
    {
        regCfgs0[1] = (ValTemp&0xff00) >> 8;
        regCfgs0[3] = ValTemp&0xff;
    }

    ValTemp = getIniItemVal("AGC1");
    if(ValTemp > 0)
    {
        regCfgs1[1] = (ValTemp&0xff00) >> 8;
        regCfgs1[3] = ValTemp&0xff;
    }

    // initialize OV5640
    for (i=0; i<sizeof(regCfgs0)/sizeof(int); i+=2)
    {
        camera0_write_i2c(regCfgs0[i], regCfgs0[i+1]);
        camera1_write_i2c(regCfgs1[i], regCfgs1[i+1]);
    }
//************* BF3003 ***************
//    int i,ValTemp = 0;
//    int regCfgs0[] =  {
//        0x0013, 0x10,
//        0x008c, 0x00, //
//        0x008d, 0x20, // AGC = 0x20
//    };
//    int regCfgs1[] =  {
//        0x0013, 0x10,
//        0x008c, 0x00, //
//        0x008d, 0x20, // AGC = 0x20
//    };

//    ValTemp = getIniItemVal("AGC0");
//    if(ValTemp > 0)
//    {
//        regCfgs0[3] = (ValTemp&0xff00) >> 8;
//        regCfgs0[5] = ValTemp&0xff;
//    }

//    ValTemp = getIniItemVal("AGC1");
//    if(ValTemp > 0)
//    {
//        regCfgs1[3] = (ValTemp&0xff00) >> 8;
//        regCfgs1[5] = ValTemp&0xff;
//    }

//    // initialize OV5640
//    for (i=0; i<sizeof(regCfgs0)/sizeof(int); i+=2)
//    {
//        camera0_write_i2c(regCfgs0[i], regCfgs0[i+1]);
//        camera1_write_i2c(regCfgs1[i], regCfgs1[i+1]);
//    }

}

void DataProvider::OV5640_AEC(int aec_on)
{
    int i,ValTemp = 0;

    int regCfgs0[] =  {
        0x3500, 0x00, // AEC = 0x400
       // 0x3501, 0x1f, //修改增益值200
        0x3501, 0x02, //
        0x3502, 0x00, //
    };
    int regCfgs1[] =  {
        0x3500, 0x00, // AEC = 0x400
        //0x3501, 0x1f, //修改增益值200
        0x3501, 0x02, //
        0x3502, 0x00, //
    };

    if(aec_on == 1){
        camera0_write_i2c(0x3503, 0x00);
        camera1_write_i2c(0x3503, 0x00);
        return;
    }
    else {
        camera0_write_i2c(0x3503, 0x03);  // AEC off /AGC off
        camera1_write_i2c(0x3503, 0x03);  // AEC off /AGC off
    }

    ValTemp = getIniItemVal("AEC0");
    if(ValTemp > 0)
    {
        regCfgs0[1] = (ValTemp&0xff0000) >> 16;
        regCfgs0[3] = (ValTemp&0xff00) >> 8;
        regCfgs0[5] = (ValTemp&0xff);
    }

    ValTemp = getIniItemVal("AEC1");
    if(ValTemp > 0)
    {
        regCfgs1[1] = (ValTemp&0xff0000) >> 16;
        regCfgs1[3] = (ValTemp&0xff00) >> 8;
        regCfgs1[5] = (ValTemp&0xff);
    }

    // initialize OV5640
    for (i=0; i<sizeof(regCfgs0)/sizeof(int); i+=2)
    {
        camera0_write_i2c(regCfgs0[i], regCfgs0[i+1]);
        camera1_write_i2c(regCfgs1[i], regCfgs1[i+1]);
    }
}


//void DataProvider::OV5640_reset(void)
//{
//    int valuefd = open("/sys/class/leds/usr_cmos/brightness", O_RDWR);


//#ifndef DESK_TOP_RUN
//    write(valuefd,"1", 2);
//#endif
//    usleep(100000);


//    SetFusionReg(rCAM0_PWR,0x80000101);
//    SetFusionReg(rCAM1_PWR,0x80000101);
//    usleep(100000);


//#ifndef DESK_TOP_RUN
//    write(valuefd,"0", 2);
//#endif
//    usleep(100000);


//    SetFusionReg(rCAM0_PWR,0x101);
//    SetFusionReg(rCAM1_PWR,0x101);
//    usleep(100000); //0.1s
//    // reset ov5640 module

//}

//void DataProvider::OV5640_read_id(unsigned int  *ov_id){

//    unsigned int  nTempVal =0;
//    unsigned int  chip_id0 =0;
//    unsigned int  chip_id1 =0;

//    nTempVal = (0x1 << 31|0x1 << 24|0x300a << 8|0x0);
//    SetFusionReg(rSCCB0_CTRCL,nTempVal);

//    while(GetFusionReg(rSCCB0_CTRCL)&(0x1 << 31)){
//        usleep(1000);
//    }

//    nTempVal = GetFusionReg(rSCCB0_READ);
//    chip_id0 = nTempVal&0xff;
//    usleep(1000000);

//    nTempVal = (0x1 << 31|0x1 << 24|0x300b << 8|0x0);
//    SetFusionReg(rSCCB0_CTRCL,nTempVal);

//    while(GetFusionReg(rSCCB0_CTRCL)&(0x1 << 31)){
//        usleep(1000);
//    }

//    nTempVal = GetFusionReg(rSCCB0_READ);
//    chip_id0 = chip_id0 << 8;
//    chip_id0 |= nTempVal&0xff;

//    printf("camera0 verify chip_id=%2x\n\r",chip_id0);

//    nTempVal = (0x1 << 31|0x1 << 24|0x300a << 8|0x0);
//    SetFusionReg(rSCCB1_CTRCL,nTempVal);

//    while(GetFusionReg(rSCCB1_CTRCL)&(0x1 << 31)){
//        usleep(1000);
//    }

//    nTempVal = GetFusionReg(rSCCB1_READ);
//    chip_id1 = nTempVal&0xff;
//    usleep(1000000);

//    nTempVal = (0x1 << 31|0x1 << 24|0x300b << 8|0x0);
//    SetFusionReg(rSCCB1_CTRCL,nTempVal);

//    while(GetFusionReg(rSCCB1_CTRCL)&(0x1 << 31)){
//        usleep(1000);
//    }

//    nTempVal = GetFusionReg(rSCCB1_READ);
//    chip_id1 = chip_id1 << 8;
//    chip_id1 |= nTempVal&0xff;

//    printf("camera1 verify chip_id=%2x\n\r",chip_id1);

//    *ov_id = ((chip_id1&0xffff) << 16)|(chip_id0&0xffff);
//}

//void DataProvider::OV5640_capture_start(void){
//    usleep(500000);
//    SetFusionReg(rCAM0_CTRL,(0x80<<24|0x80<<16));// start video
//    usleep(500000);
//    SetFusionReg(rCAM1_CTRL,(0x80<<24|0x80<<16));
//    qDebug("camera0 data count=%d ,camera1 data count=%d .",GetFusionReg(rCAM0_PARAM),GetFusionReg(rCAM1_PARAM));
//}

//void DataProvider::OV5640_init(void) {
//    qDebug("******************************************************************");
//    qDebug("*************     CAMERA TEST START         **********************");
//    qDebug("******************************************************************");

//    my_cmosStartOver = false;
//    OV5640_reset();
//    OV5640_read_id(&ov_id);
//    OV5640_init_setting();

//    OV5640_vga30fps_config();

//    OV5640_AEC(0);
//    OV5640_AGC(0);
//    emit this->displayCMOS();
//    OV5640_capture_start();
//    my_cmosStartOver = true;

//    //qDebug("read ov_id = %x",ov_id);
//}

void DataProvider::Get_FiberXEdge(unsigned int edge_cnt){
    unsigned int nI,nJ;
    unsigned int fiber_info[256];

    if(edge_cnt > 3) {
        qDebug("Wrong edge cnt,must less than edge3");
        return;
    }

    while(GetFusionReg(rINFO_READY0)&0x1 == 0x0);
    GetFusionMem(1024 + edge_cnt*256,256,fiber_info);

    for(nI = 0;nI < 256;nI++){
         fiberx_info[nI] = (fiber_info[nI]&0xffff0000) >> 16;
         fiberx_edge[nI] = (fiber_info[nI]&0x0000ffff);
    }
}

void DataProvider::Get_FiberYEdge(unsigned int edge_cnt){
    unsigned int nI,nJ;
    unsigned int fiber_info[256];

    if(edge_cnt > 3) {
        qDebug("Wrong edge cnt,must less than edge3");
        return;
    }

    while(GetFusionReg(rINFO_READY1)&0x1 == 0x0);
    GetFusionMem(2048 + edge_cnt*256,256,fiber_info);

    for(nI = 0;nI < 256;nI++){
        fibery_info[nI]  = (fiber_info[nI]&0xffff0000) >> 16;
        fibery_edge[nI] = (fiber_info[nI]&0x0000ffff);
    }
}


void DataProvider::BaseLineReset(int * baseline)
{
    int base   = getIniItemVal("MeltPosition");


    base = (base > 0)?base:320;
    * baseline = (base << 16)|base;
    /*
    int offset = getIniItemVal("YBasePosition");
    offset = (base > 0)?offset:320;
    base   -= 320;
    offset -= 320;
    OV5640_XOFFSET(0,3*base);
    OV5640_XOFFSET(1,-3*offset);
    */
}

unsigned int DataProvider::average10(volatile unsigned int source[10]) {
    unsigned char i;
    unsigned int max, min;
    unsigned int accumulater;

    accumulater = source[0];
    max = min = source[0];
    for (i = 1; i < 10; i++) {
        if (source[i] < min)
            min = source[i];
        if (source[i] > max)
            max = source[i];

        accumulater += source[i];
    }
    return (accumulater - max - min);
}

unsigned int DataProvider::duanmian_process(unsigned int q[50], unsigned int d[50],unsigned int c[50],unsigned int *diameter,unsigned int *core,unsigned int *face)
{
    unsigned int i, j, k, s, g,h,z,v, result;
    volatile unsigned int bx[10],dx[10],cx[10];

    *diameter = 0;
    *core  = 0;
    result = 0;

    //search start point
    s = 0;
    z = 0;
    for (i = 0; i < 49; i++) {
        if ((q[i] != 0x0) && (q[i + 1] != 0x0)) {
            s = i;
            break;
        }
    }

    //search continues 10 good points,and mark g as the last point
    k = 0;
    g = 1000;
    for (i = s; i < 49; i++) {
        if (q[i] == 0x4)
            k++;
        else {
            k = 0;
        }
        if (k == 10) {
            g = i;
            break;
        }
    }

    j = 0;
    h = (g - 9 - s);
    v = 0;

    if (k < 10){
        result = 1;
    }
    else {
        for (i = (g - 9); i < (g + 1); i++) {
            dx[j] = d[i];
            cx[j] = c[i];
            //qDebug("duanmian_process:j=%d,q=%x,dx=%d,cx=%d;", j, q[i], d[i],c[i]);
            j++;
        }

        j = 0;
        for (i = 40; i < 49; i++) {
            bx[j] = d[i];
            j++;
        }
        z = average10(bx);

        *diameter = average10(dx);
        *core     = average10(cx);
        v         = abs(*diameter - z);

        if(FiberMaxAngle > 40){
            *face = h + v/64;
        }
        if(FiberMaxAngle > 30){
            *face = h + v/32;
        }
        else if(FiberMaxAngle > 20){
            *face = h + v/16;
        }
        if(FiberMaxAngle > 10){
            *face = h + v/8;
        }
        else {
            *face = h + v;
        }

        if(*face > FiberMaxAngle) result = 1;
    }

    qDebug("duanmian_process:result=%d,s=%d h=%d z=%d v=%d ang=%d;",result,s,h,z,v,FiberMaxAngle);
    return result;
}


void DataProvider::cliberate_process(){
    unsigned int caliberate_edge;
    unsigned int InitPos;

    InitPos = (getIniItemVal("MeltPosition"))&0x0000ffff;
    usleep(600000); //wait update

    caliberate_edge = GetFusionReg(rCALIB_EDG0);
    gap_info[0] = caliberate_edge&0xffff;
    gap_info[1] = (caliberate_edge&0xffff0000) >> 16;
    gap_info[2] = InitPos - gap_info[0];
    gap_info[3] = gap_info[1] - InitPos;

    qDebug("Caliberation::a1=%d,a2=%d,a3=%d,a4=%d",gap_info[0],gap_info[1],gap_info[2],gap_info[3]);
}


//放电校准
void DataProvider::getCaliberationInfo(int info[5])
{
    int InitForce;
    int InitPos;
    int InitStdMax;
    int InitStdMin;

    int AdjForce;
    int CalibMax;
    int CalibMin;
    int CalibNom;

    qreal step;
    qreal bias;

    if(nProgParamSel == 0) {
        InitForce  = (getIniItemVal("SingleMeltIntense"))&0x000000ff;
        InitStdMax = (getIniItemVal("SingleMeltStdMax"))&0x000001ff;
        InitStdMin = (getIniItemVal("SingleMeltStdMin"))&0x00000ff;
    }
    else {
        InitForce = (getIniItemVal("MultiMeltIntense"))&0x000000ff;
        InitStdMax = (getIniItemVal("MultiMeltStdMax"))&0x000001ff;
        InitStdMin = (getIniItemVal("MultiMeltStdMin"))&0x00000ff;
    }
    InitPos   = (getIniItemVal("MeltPosition"))&0x0000ffff;

    if(InitPos == 0)   InitPos   = 320;
    if(InitForce == 0) InitForce = 60;

    if((InitStdMax == 0)||(InitStdMin == 0)){
        CalibMax = (nProgParamSel == 0)?160:360;
        CalibMin = (nProgParamSel == 0)?110:310;
    }
    else {
        CalibMax = InitStdMax;
        CalibMin = InitStdMin;
    }


    CalibNom = (CalibMax + CalibMin) / 2;

    step     = InitForce*(abs((gap_info[2] + gap_info[3] - CalibNom)))/320;
    bias     = abs((gap_info[2] - gap_info[3]))/2;
    AdjForce = (int) (step + 1.0);

    info[4]  = 0;
    info[0]  = InitForce;

    if((gap_info[2] + gap_info[3]) > CalibMax) {
        info[1]  = (InitForce > AdjForce)?(InitForce - AdjForce):(InitForce/2);
        info[4] |= 0x1;
    }
    else if((gap_info[2] + gap_info[3]) < CalibMin){
        info[1]  = ((InitForce + AdjForce) > 255)?255:(InitForce + AdjForce);
        info[4] |= 0x2;
    }
    else {
        info[1] = InitForce;
    }

    info[2] = InitPos;
    if(abs(gap_info[2] - gap_info[3]) > 15){
        if((gap_info[2] > gap_info[3])) {
            info[3]  = InitPos - bias;
            info[4] |= 0x4;
        }
        else {
            info[3]  = InitPos + bias;
            info[4] |= 0x8;
        }
    }
    else {
        info[3] = InitPos;
    }

    if(info[2] == info[3]) info[4] &= 0x3;

    if((info[4] & 0xc) == 0){ //位置正常
        PositionSuggested   = info[2];
    }
    else {
        PositionSuggested   = info[3];
    }

    if((info[4] & 0x3) == 0){ //强度正常
        IntenseSuggested    = (info[0] > 255)?255:info[0];
        PreIntenseSuggested = (info[0] > 10 )?(info[0] - 10):10;
    }
    else {
        IntenseSuggested    = (info[1] > 255)?255:info[1];
        PreIntenseSuggested = (info[1] > 10 )?(info[1] - 10):10;
    }

    for(int nI=0;nI<5;nI++) qDebug("info[%d]=%d",nI,info[nI]);
    qDebug("ParamSel=%d caliberate::MeltIntense=%d PreMeltIntense=%d MeltPosition=%d",nProgParamSel,IntenseSuggested,PreIntenseSuggested,PositionSuggested);

}

void DataProvider::joint_process_x()
{

    unsigned int fiber_edge0[256];
    unsigned int fiber_edge3[256];
    unsigned int fiber_info0[256];
    unsigned int fiber_info3[256];
    unsigned int fiber_zijin[256];

    unsigned int nI,nJ;
    unsigned int q[50];
    unsigned int d[50];
    unsigned int c[50];


    unsigned int diameter;
    unsigned int bob_point;
    unsigned int core ;

    unsigned int i, j, k, result;
    unsigned int m, n, v;
    volatile unsigned int dx[10],cx[10];

    while(GetFusionReg(rINFO_READY0)&0x1 == 0x0);
    GetFusionMem(1024 + 0,256,fiber_info0);
    GetFusionMem(1024 + 768,256,fiber_info3);

    for(nI = 0;nI < 256;nI++){
         fiber_edge0[nI] = (fiber_info0[nI]&0x0000ffff);
         fiber_edge3[nI] = (fiber_info3[nI]&0x0000ffff);
         fiberx_info[nI] = (fiber_info0[nI]&0xffff0000) >> 16;
         fiberx_core[nI] = fiber_edge3[nI] + fiber_edge0[nI];
         fiber_zijin[nI] = fiber_edge3[nI] - fiber_edge0[nI];
    }

    for(i = 0; i < 50; i++)
    {
        d[i]  = fiber_zijin[(103 + i)];
        q[i]  = fiberx_info[(103 + i)];
        c[i]  = fiberx_core[(103 + i)];
    }


    diameter = 0;
    core  = 0;
    result = 0;
    bob_point = 0;
    //search continues 10 good points,and mark g as the last point
    j = 0;
    k = 0;
    for (i = 0; i < 50; i++) {
        if (q[i] == 0x4)
            k++;
        else {
            k = 0;
        }

        if(i%5 == 0) {
            dx[j] = d[i];
            cx[j] = c[i];
            j++;
        }
    }

    bob_point = 50 - k;
    if (bob_point > bob_allow) result = 1; //bad joint ,not contiouse
    qDebug("joint_process_x::bob_point=%d,max_bob=%d,result=%d",bob_point,bob_allow,result);

    k=0;
    n=0;
    v=0;
    if(result == 0) {
        m = average10(dx)/8;
        for (i = 0; i < 10;i++) {
            if(dx[i] > m) n = dx[i]-m;
            else  n = m - dx[i];

            if(n>v) v = n;
            if(n > fusion_max_diam_diff) k++;
        }
    }

    diameter = v;
    if (k > 3) result += 2; //bad joint ,diameter different
    qDebug("joint_process_x::diameter_diff=%d,max_diam_diff=%d,result=%d",diameter,fusion_max_diam_diff,result);

    k=0;
    n=0;
    v=0;
    if(result == 0) {
        m = average10(cx)/8;
        for (i = 0; i < 10;i++) {
            if(cx[i] > m) n = cx[i]-m;
            else  n = m - cx[i];

            if(n>v) v = n;
            if(n > fusion_max_core_diff) k++;
        }
    }

    core = v;
    if (k > 3) result += 4; //bad joint ,core different

    if(FiberMaxAngle >= 40) result &= 0x0;
    else if(FiberMaxAngle >= 30) result &= 0x1;
    else if(FiberMaxAngle >= 20) result &= 0x3;
    else result &= 0x7;

    qDebug("joint_process_x::core_diff=%d,max_core_diff=%d,result=%d",core,fusion_max_core_diff,result);

    //qDebug() << "result::" <<  result << "diameter::"<< diameter << "core::"<< core << "bob_point::" << bob_point <<__FILE__<<__LINE__;


    joint_info[20] = result;
    joint_info[21] = diameter;
    joint_info[22] = core;
    joint_info[23] = bob_point;
}

void DataProvider::joint_process_y()
{

    unsigned int fiber_edge0[256];
    unsigned int fiber_edge3[256];
    unsigned int fiber_info0[256];
    unsigned int fiber_info3[256];
    unsigned int fiber_zijin[256];

    unsigned int nI,nJ;
    unsigned int q[50];
    unsigned int d[50];
    unsigned int c[50];


    unsigned int diameter;
    unsigned int bob_point;
    unsigned int core ;

    unsigned int i, j, k, result;
    unsigned int m, n, v;
    volatile unsigned int dx[10],cx[10];

    while(GetFusionReg(rINFO_READY1)&0x1 == 0x0);
    GetFusionMem(2048 + 0,256,fiber_info0);
    GetFusionMem(2048 + 768,256,fiber_info3);

    for(nI = 0;nI < 256;nI++){
         fiber_edge0[nI] = (fiber_info0[nI]&0x0000ffff);
         fiber_edge3[nI] = (fiber_info3[nI]&0x0000ffff);
         fibery_info[nI] = (fiber_info0[nI]&0xffff0000) >> 16;
         fibery_core[nI] = fiber_edge3[nI] + fiber_edge0[nI];
         fiber_zijin[nI] = fiber_edge3[nI] - fiber_edge0[nI];
    }

    for(i = 0; i < 50; i++)
    {
        d[i] = fiber_zijin[(103 + i)];
        q[i] = fibery_info[(103 + i)];
        c[i] = fibery_core[(103 + i)];
    }


    diameter = 0;
    core  = 0;
    result = 0;
    bob_point = 0;
    //search continues 10 good points,and mark g as the last point
    j = 0;
    k = 0;
    for (i = 0; i < 50; i++) {
        if (q[i] == 0x4)
            k++;
        else {
            k = 0;
        }

        if(i%5 == 0) {
            dx[j] = d[i];
            cx[j] = c[i];
            j++;
        }
    }

    bob_point = 50 - k;
    if (bob_point > bob_allow) result = 1; //bad joint ,not contiouse
    qDebug("joint_process_y::bob_point=%d,max_bob=%d,result=%d",bob_point,bob_allow,result);

    k=0;
    n=0;
    v=0;
    if(result == 0) {
        m = average10(dx)/8;
        for (i = 0; i < 10;i++) {
            if(dx[i] > m) n = dx[i]-m;
            else  n = m - dx[i];

            if(n>v) v = n;
            if(n > fusion_max_diam_diff) k++;
        }
    }

    diameter = v;
    if (k > 3) result += 2; //bad joint ,diameter different
    qDebug("joint_process_y::diameter_diff=%d,max_core_diff=%d,result=%d",diameter,fusion_max_diam_diff,result);

    k=0;
    n=0;
    v=0;
    if(result == 0) {
        m = average10(cx)/8;
        for (i = 0; i < 10;i++) {
            if(cx[i] > m) n = cx[i]-m;
            else  n = m - cx[i];

            if(n>v) v = n;
            if(n > fusion_max_core_diff) k++;
        }
    }

    core = v;
    if (k > 3) result += 4; //bad joint ,core different

    if(FiberMaxAngle >= 40) result &= 0x0;
    else if(FiberMaxAngle >= 30) result &= 0x1;
    else if(FiberMaxAngle >= 20) result &= 0x3;
    else result &= 0x7;
    qDebug("joint_process_y::core_diff=%d,max_core_diff=%d,result=%d",core,fusion_max_core_diff,result);

    //qDebug() << "result::" <<  result << "diameter::"<< diameter << "core::"<< core << "bob_point::" << bob_point <<__FILE__<<__LINE__;
    joint_info[25] = result;
    joint_info[26] = diameter;
    joint_info[27] = core;
    joint_info[28] = bob_point;
}

void DataProvider::Get_FiberCoreX(
        unsigned int* core_l,unsigned int* core_r,
        unsigned int* diameter_l, unsigned int *diameter_r,
        unsigned int* face_l, unsigned int *face_r)
{
    unsigned int fiber_edge0[256];
    unsigned int fiber_edge3[256];
    unsigned int fiber_info0[256];
    unsigned int fiber_info3[256];
    unsigned int fiber_zijin[256];

    unsigned int ql[50] , qr[50] ;
    unsigned int dl[50] , dr[50] ;
    unsigned int cl[50] , cr[50] ;

    while(GetFusionReg(rINFO_READY0)&0x1 == 0x0);
    GetFusionMem(1024 + 0,256,fiber_info0);
    GetFusionMem(1024 + 768,256,fiber_info3);

    for(int nI = 0;nI < 256;nI++){
        fiber_edge0[nI] = (fiber_info0[nI]&0x0000ffff);
        fiber_edge3[nI] = (fiber_info3[nI]&0x0000ffff);
        fiberx_info[nI] = (fiber_info0[nI]&0xffff0000) >> 16;
        fiberx_core[nI] = fiber_edge3[nI] + fiber_edge0[nI];
        fiber_zijin[nI] = fiber_edge3[nI] - fiber_edge0[nI];
    }

    for(int nI = 0; nI < 50; nI++)
    {
        dl[nI] = fiber_zijin[(128 - FiberGap - nI)];
        ql[nI] = fiberx_info[(128 - FiberGap - nI)];
        cl[nI] = fiberx_core[(128 - FiberGap - nI)];
        dr[nI] = fiber_zijin[(128 + FiberGap + nI)];
        qr[nI] = fiberx_info[(128 + FiberGap + nI)];
        cr[nI] = fiberx_core[(128 + FiberGap + nI)];
    }

    face_result_xl += duanmian_process(ql,dl,cl,diameter_l,core_l,face_l);
    face_result_xr += duanmian_process(qr,dr,cr,diameter_r,core_r,face_r);

    if (FiberMaxAngle > 25) return;
    if ((diameter_r > (FiberDiameterMaxDiff + diameter_l))||(diameter_l  > (FiberDiameterMaxDiff + diameter_r)))
    {
        qWarning("diameter_test:X_view diameter_r=%d, diameter_l=%d;",diameter_r, diameter_l);
        face_result_xl += 10000;
        face_result_xr += 10000;
    }
}

void DataProvider::Get_FiberCoreY(
        unsigned int* core_l,unsigned int* core_r,
        unsigned int* diameter_l, unsigned int *diameter_r,
        unsigned int* face_l, unsigned int *face_r)
{
    unsigned int fiber_edge0[256];
    unsigned int fiber_edge3[256];
    unsigned int fiber_info0[256];
    unsigned int fiber_info3[256];
    unsigned int fiber_zijin[256];

    unsigned int ql[50] , qr[50] ;
    unsigned int dl[50] , dr[50] ;
    unsigned int cl[50] , cr[50] ;

    while(GetFusionReg(rINFO_READY1)&0x1 == 0x0);
    GetFusionMem(2048 + 0,256,fiber_info0);
    GetFusionMem(2048 + 768,256,fiber_info3);

    for(int nI = 0;nI < 256;nI++){
        fiber_edge0[nI] = (fiber_info0[nI]&0x0000ffff);
        fiber_edge3[nI] = (fiber_info3[nI]&0x0000ffff);
        fibery_info[nI] = (fiber_info0[nI]&0xffff0000) >> 16;
        fibery_core[nI] = fiber_edge3[nI] + fiber_edge0[nI];
        fiber_zijin[nI] = fiber_edge3[nI] - fiber_edge0[nI];
    }

    for(int nI = 0; nI < 50; nI++)
    {
        dl[nI] = fiber_zijin[(128 - FiberGap - nI)];
        ql[nI] = fibery_info[(128 - FiberGap - nI)];
        cl[nI] = fibery_core[(128 - FiberGap - nI)];
        dr[nI] = fiber_zijin[(128 + FiberGap + nI)];
        qr[nI] = fibery_info[(128 + FiberGap + nI)];
        cr[nI] = fibery_core[(128 + FiberGap + nI)];
    }

    face_result_yl += duanmian_process(ql,dl,cl,diameter_l,core_l,face_l);
    face_result_yr += duanmian_process(qr,dr,cr,diameter_r,core_r,face_r);

    if (FiberMaxAngle > 25) return;
    if ((diameter_r > (FiberDiameterMaxDiff + diameter_l))||(diameter_l  > (FiberDiameterMaxDiff + diameter_r))){
        qWarning("diameter_test:Y_view diameter_r=%d, diameter_l=%d; result=%d",diameter_r, diameter_l);
        face_result_yl += 10000;
        face_result_yr += 10000;
     }
}

unsigned int DataProvider::x_edge_move(unsigned int m3,unsigned int m4,unsigned int diff_prev,unsigned int* diff_get)
{

    int diff = ::abs(m3 - m4);
    *diff_get = diff;

    /*if((diff - diff_prev) > burst_points){
        dirct_x = !(dirct_x);
        dirct_change_x ++ ;
    }*/

    if(m3 > (m4 + edge_rough_offset))
    {
        x_motor_ctrl(1,1,1,0,0,0xffff);
    }
    else if(m4 > (m3 + edge_rough_offset))
    {
        x_motor_ctrl(1,1,0,0,0,0xffff);
    }
    else
    {
        qDebug("m3=%d m4=%d diff=%d allow=%d",m3,m4,diff,edge_rough_offset);
        x_motor_ctrl(1,1,1,1,1,0x0);
        return 1;
    }

    return 0;
}

unsigned int DataProvider::x_core_move(unsigned int m3,unsigned int m4,unsigned int diff_prev,unsigned int* diff_get)
{

    int diff = ::abs(m3 - m4);
    *diff_get = diff;

    /*if((diff - diff_prev) > burst_points){
        dirct_x = !(dirct_x);
        dirct_change_x ++ ;
    }*/

    if(m3 > (m4 + FiberRoughPoints))
    {
        x_motor_ctrl(1,1,1,0,0,0xffff);
    }
    else if(m4 > (m3 + FiberRoughPoints))
    {
        x_motor_ctrl(1,1,0,0,0,0xffff);
    }
    else if(m3 > (m4 + FiberAccuratePoints))
    {
        x_motor_ctrl(1,5,1,0,0,0xffff);
    }
    else if(m4 > (m3 + FiberAccuratePoints))
    {
        x_motor_ctrl(1,5,0,0,0,0xffff);
    }
    else
    {
        qDebug("m3=%d m4=%d diff=%d allow=%d",m3,m4,diff,FiberAccuratePoints);
        x_motor_ctrl(1,1,1,1,1,0x0);
        return 1;
    }

    return 0;
}

unsigned int DataProvider::y_edge_move(unsigned int m3,unsigned int m4,unsigned int diff_prev,unsigned int* diff_get)
{
    int  diff = ::abs(m3 - m4);
    *diff_get = diff;

    /*if((diff - diff_prev) > burst_points) {
        dirct_y = !(dirct_y);
        dirct_change_y ++ ;
    }*/

    if(m3 > (m4 + edge_rough_offset)){
        y_motor_ctrl(1,1,1,0,0,0xffff);
    }
    else if(m4 > (m3 + edge_rough_offset)){
        y_motor_ctrl(1,1,0,0,0,0xffff);
    }
    else {
        qDebug("m3=%d m4=%d diff=%d allow=%d",m3,m4,diff,edge_rough_offset);
        y_motor_ctrl(1,1,1,1,1,0x0);
        return 1;
    }

    return 0;
}

unsigned int DataProvider::y_core_move(unsigned int m3,unsigned int m4,unsigned int diff_prev,unsigned int* diff_get)
{
    int  diff = ::abs(m3 - m4);
    *diff_get = diff;

    /*if((diff - diff_prev) > burst_points) {
        dirct_y = !(dirct_y);
        dirct_change_y ++ ;
    }*/

    if(m3 > (m4 + FiberRoughPoints)){
        y_motor_ctrl(1,1,1,0,0,0xffff);
    }
    else if(m4 > (m3 + FiberRoughPoints)){
        y_motor_ctrl(1,1,0,0,0,0xffff);
    }
    else if(m3 > (m4 + FiberAccuratePoints)){
        y_motor_ctrl(1,5,1,0,0,0xffff);
    }
    else if(m4 > (m3 + FiberAccuratePoints)){
        y_motor_ctrl(1,5,0,0,0,0xffff);
    }
    else {
        qDebug("m3=%d m4=%d diff=%d allow=%d",m3,m4,diff,FiberAccuratePoints);
        y_motor_ctrl(1,1,1,1,1,0x0);
        return 1;
    }

    return 0;
}

int DataProvider::getManualSpeed()
{
    return getIniItemVal("ManualSpeed");
}

void DataProvider::Fiber_edge_x(unsigned int* m3,unsigned int* m4)
{
    unsigned int nI;

    nI = GetFusionReg(rENGIN_EDG0);
    *m3 = (nI >> 16)&0xffff;
    *m4 = nI&0xffff;
}

void DataProvider::Fiber_edge_y(unsigned int* m3,unsigned int* m4)
{
    unsigned int nI;

    nI = GetFusionReg(rENGIN_EDG1);
    *m3 = (nI >> 16)&0xffff;
    *m4 = nI&0xffff;
}

void DataProvider::Fiber_bright(unsigned int* m3,unsigned int* m4)
{
    unsigned int nI;

    nI = GetFusionReg(rCALIB_BRHT);
    *m3 = (nI >> 16)&0xff;
    *m4 = nI&0xff;
}

void DataProvider::Fiber_adjust_x()
{
    unsigned int m0,m3,m4,m5,m6;

    qDebug("Fiber_adjust_x start::");
    m5 = 1000000;
    for(align_cnt_x = 0;align_cnt_x < fusion_max_align; align_cnt_x++)
    {
        usleep(50000);

        Fiber_edge_x(&m4,&m3);
        m0 = x_edge_move(8*m3,8*m4,m5,&m6);

        qDebug("Fiber_adjust_x[%8d]:: xl_accum = %8x xr_accum = %8x",align_cnt_x,m5,m6);

        if(m0 > 0) break;
        if(meltState == MeltReset) break;
        m5 = m6;
    }    

    x_motor_ctrl(1,1,1,1,1,0x0);//force motor stop

    if(m0 > 0){
        return;
    }
}


void DataProvider::Fiber_adjust_y()
{
    unsigned int m0,m3,m4,m5,m6;
    unsigned int nI;

    qDebug("Fiber_adjust_y start::");
    m5 = 1000000;
    for(align_cnt_y = 0;align_cnt_y < fusion_max_align; align_cnt_y++)
    {
        usleep(50000);

        Fiber_edge_y(&m4,&m3);
        m0 = y_edge_move(8*m3,8*m4,m5,&m6);
        qDebug("Fiber_adjust_y[%8d]:: yl_accum = %8x yr_accum = %8x",align_cnt_y,m5,m6);

        if(m0 > 0) break;
        if(meltState == MeltReset) break;

        m5 = m6;
    }

    //force motor stop
    y_motor_ctrl(1,1,1,1,1,0x0);

    if(m0 > 0){
        return;
    }
}

void DataProvider::Fiber_align_x()
{
    unsigned int mf,m0,m1,m2,m3,m4,m5,m6,m7,m8;

    qDebug("Fiber_align_x start::");
    m7 = 1000000;
    for(align_cnt_x = 0;align_cnt_x < fusion_max_align; align_cnt_x++)
    {
        Get_FiberCoreX(&m3,&m4,&m1,&m2,&m5,&m6);
        usleep(10000);
        if((face_result_xl >= MAX_IGNOR_BAD)||(face_result_xr >= MAX_IGNOR_BAD)){
            qDebug("Fiber_align_x::Bad end face");
            break;
        }

        m0 = x_core_move(m3,m4,m7,&m8);
        qDebug("Fiber_align_x[%8d]:: xl_accum = %8x xr_accum = %8x",align_cnt_x,m7,m8);

        if(m0 > 0) break;
        if(meltState == MeltReset) break;
        m7 = m8;
    }
    x_motor_ctrl(1,1,1,1,1,0x0);//force motor stop

    joint_info[0] = fiberx_edge[8];  // edge l
    joint_info[1] = fiberx_edge[248];// edge r
    joint_info[2] = m3; // core l
    joint_info[3] = m4; // core r
    joint_info[4] = m1; // diam l
    joint_info[5] = m2; // diam r
    joint_info[6] = m5; // face l
    joint_info[7] = m6; // face r

    if((m0 > 0)||(face_result_xl >= MAX_IGNOR_BAD)||(face_result_xr >= MAX_IGNOR_BAD)){
        return;
    }
    else if((dirct_change_x > max_allow_change)||(align_cnt_x >= fusion_max_align)) {
        face_result_xl = 10000;
        face_result_xr = 10000;
    }
}

bool  DataProvider::hasFace()
{
    if( (face_result_xl == 10000) && (face_result_xr == 10000))
    {
       return true;
    }else{
        return false;
    }
}

void DataProvider::Fiber_align_y()
{
    unsigned int m0,m1,m2,m3,m4,m5,m6,m7,m8;

    qDebug("Fiber_align_y start::");

    m7 = 1000000;
    for(align_cnt_y = 0;align_cnt_y < fusion_max_align; align_cnt_y++)
    {
        Get_FiberCoreY(&m3,&m4,&m1,&m2,&m5,&m6);
        usleep(10000);
        if((face_result_yl >= MAX_IGNOR_BAD)||(face_result_yr >= MAX_IGNOR_BAD)){
            qDebug("Fiber_align_y::Bad end face");
            break;
        }
        m0 = y_core_move(m3,m4,m7,&m8);

        qDebug("Fiber_align_y[%8d]:: yl_accum = %8x yr_accum = %8x",align_cnt_y,m7,m8);
        m7 = m8;

        if(m0 > 0) break;
        if(meltState == MeltReset) break;
    }

    joint_info[10] = fibery_edge[8];  // edge l
    joint_info[11] = fibery_edge[248];// edge r
    joint_info[12] = m3; // core l
    joint_info[13] = m4; // core r
    joint_info[14] = m1; // diam l
    joint_info[15] = m2; // diam r
    joint_info[16] = m5; // face l
    joint_info[17] = m6; // face r

    y_motor_ctrl(1,1,1,1,1,0x0); //force motor stop

    if((m0 > 0)||(face_result_yl >= MAX_IGNOR_BAD)||(face_result_yr >= MAX_IGNOR_BAD)){
        return;
    }
    else if((dirct_change_y > max_allow_change)||(align_cnt_y >= fusion_max_align)) {
        face_result_yl = 10000;
        face_result_yr = 10000;
    }
}

void DataProvider::pushing_speed_set(unsigned int speed){
    unsigned int motor_sets;

    motor_sets  = GetFusionReg(rMOTOR_SPPED);
    SetFusionReg(rMOTOR_SPPED,(motor_sets & 0xffff0000)|(speed&0x0000ffff));
}

void DataProvider::adjust_speed_set(unsigned int speed){
    unsigned int motor_sets;

    motor_sets  = GetFusionReg(rMOTOR_SPPED);
    SetFusionReg(rMOTOR_SPPED, (motor_sets & 0x0000ffff)|(speed << 16));
}

void DataProvider::l_motor_ctrl(unsigned int cpu_ctrl,unsigned int speed,unsigned int dirction,unsigned int on_off,unsigned int pause,unsigned int angle){
    SetFusionReg(rL_MOTOR, (angle<<16)|(speed << 8)|(cpu_ctrl << 3)|(dirction << 2)|(pause << 1)|on_off);
}

void DataProvider::r_motor_ctrl(unsigned int cpu_ctrl,unsigned int speed,unsigned int dirction,unsigned int on_off,unsigned int pause,unsigned int angle){
    SetFusionReg(rR_MOTOR, (angle<<16)|(speed << 8)|(cpu_ctrl << 3)|(dirction << 2)|(pause << 1)|on_off);
}

void DataProvider::x_motor_ctrl(unsigned int cpu_ctrl,unsigned int speed,unsigned int dirction,unsigned int on_off,unsigned int pause,unsigned int angle){    
    SetFusionReg(rX_MOTOR, (angle<<16)|(speed << 8)|(cpu_ctrl << 3)|(dirction << 2)|(pause << 1)|on_off);
}

void DataProvider::y_motor_ctrl(unsigned int cpu_ctrl,unsigned int speed,unsigned int dirction,unsigned int on_off,unsigned int pause,unsigned int angle){
    SetFusionReg(rY_MOTOR, (angle<<16)|(speed << 8)|(cpu_ctrl << 3)|(dirction << 2)|(pause << 1)|on_off);
}

void DataProvider::InitBatGrade()
{

    getBatGrade();
}

QList<int>  DataProvider::getBatGrade()
{

    int   bat_adc;
    int t_Perc,t_Prog;
    float grade_real = 0.00;
    QList<int> t_LitsNum;
    t_LitsNum << 0 << 0 << 0 << 0 << 0 << 0; //百分比， 显示进度  是否充电1，二级报警1，一级报警1,没电池有适配器为1,有电池有适配器为0

    bat_adc     = GetFusionReg(rVPIN);
    grade_real  = (float)(bat_adc - MIN_VOLTAGE)/(float)(MAX_VOLTAGE - MIN_VOLTAGE) ; // between 12.6 V -- 10.6 V

     if( grade_real <= 0 )
     {
        grade_real = 0;
     }else if ( grade_real >= 1)
     {
        grade_real = 1;
     }

     t_Perc = grade_real*100;
     t_Prog = grade_real*10;


    if((bat_adc <= 2130)  && (GetFusionReg(rVTMP) >=  65530)) //没有电池，只有电源适配器
    {
        t_LitsNum[5] = 1;
        t_LitsNum[0] = 100;
        t_LitsNum[1] = 10;
    }else if( (bat_adc >2130) &&   (bat_adc <= MMM_VOLTAGE))     //超过最低电压值 10.1  --- 10.3   一级充电提示
    {
        t_LitsNum[4] = 1;
        my_poweroffCount++;
        if( my_poweroffCount == 1)
        {
            my_messageEnable = true;
            emit powerOff(1);
        }
        if( my_poweroffCount >20) //倒计时20S后关机
        {
           my_poweroffCount = 0;

           this->pwroff();
        }

    }else if( (bat_adc > MMM_VOLTAGE) && (bat_adc <= MIN_VOLTAGE)){ //二级充电提示 10.3 -- 10.5
        t_LitsNum[3] = 1;
        my_poweroffCount = 0;
        if( my_messageEnable )
        {
            emit powerOff(2);
            my_messageEnable = false;
        }

    } else if ( (bat_adc > MIN_VOLTAGE) &&  (GetFusionReg(rVTMP) >=  65530) )//充电检测
    {
         my_poweroffCount = 0;
         t_LitsNum[2] = 1; //正在充电
         if( my_messageEnable )
         {
             emit powerOff(2);
             my_messageEnable = false;
         }

         if ( bat_adc < 34600)    //分段补偿
         {
             t_LitsNum[0] = t_Perc-20;           //转换为百分比
              t_LitsNum[1] = t_Prog-2;             //转换为格子数量
         }else if ( bat_adc < 49600 ){
             t_LitsNum[0] = t_Perc-13.5;
              t_LitsNum[1] = t_Prog-1.4;
         }else {
             t_LitsNum[0] = t_Perc-5;
              t_LitsNum[1] = t_Prog-0.5;
         }
    }else if ( (bat_adc >= MIN_VOLTAGE) ){
        t_LitsNum[0] = t_Perc;           //转换为百分比
        t_LitsNum[1] = t_Prog;            //转换为格子数量
        t_LitsNum[2] = 0; //拔掉适配器
    }

    my_batPer = 10.3 + t_Prog*0.18;

   //qDebug() << t_LitsNum  << my_poweroffCount  << my_batPer<<t_Prog << grade_real <<bat_adc<<__FILE__<<__LINE__;

    return t_LitsNum;


}
float DataProvider::getBattery()
{
    return my_batPer;
}



unsigned int DataProvider::getFaceResult()
{
    unsigned int face_result = 0;

    if((face_result_xl >= MAX_IGNOR_BAD)||(face_result_yl >= MAX_IGNOR_BAD)) face_result |= 0x1;
    if((face_result_xr >= MAX_IGNOR_BAD)||(face_result_yr >= MAX_IGNOR_BAD)) face_result |= 0x2;

    return face_result;
}

//获取所有参数，目前为了测试，将所有参数在此处写为定值

void DataProvider::clearFusionCfgs()
{

    meltMode    = (MeltMode)   getIniItemVal("MeltMode");
    int ValTemp              = getIniItemVal("FusionMaxAlign");
    switch(meltMode)
    {
        case Auto:
            setMeltMode(Auto);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x300);
            break;
        case Manual:
            setMeltMode(Manual);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xfffffe00)|0x002);
            break;
        case Pause3:
            setMeltMode(Pause3);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x306);
            break;
        case Pause2:
            setMeltMode(Pause2);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x304);
            break;
        case Pause1:
            setMeltMode(Pause1);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x302);
            break;
        case Calibe:
            setMeltMode(Calibe);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x101);//set caliberation_mod
        default:
            break;
    }
}

void DataProvider::InitFusionCfgs()
{
    int i,ValTemp,baseline;

    meltMode    = (MeltMode)   getIniItemVal("MeltMode");
    heatingMode = (HeatingMode)getIniItemVal("HeatingMode");
    spdMode     = (SpeedMode)  getIniItemVal("SpeedMode");


    ValTemp              = getIniItemVal("FusionMaxAlign");
    fusion_max_align     = (ValTemp > 100)?ValTemp:500;

    ValTemp              = getIniItemVal("FaceAngle");
    i                    = (spdMode == Precise)?1:3;
    fusion_max_diam_diff = i*((ValTemp/10) + 2);
    fusion_max_core_diff = i*((ValTemp/10) + 5);

    ValTemp = (0x80<<24|0x80 << 16);
    //ValTemp = (0x80<<24);
    SetFusionReg(rCAM0_CTRL,ValTemp);
    SetFusionReg(rCAM1_CTRL,ValTemp);

    BaseLineReset(&baseline);
    SetFusionReg(rBASE_X,baseline);
    usleep(100000);

    switch(meltMode)
    {   
        case Auto:
            setMeltMode(Auto);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x300);
            break;
        case Manual:
            setMeltMode(Manual);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xfffffe00)|0x002);
            break;
        case Pause3:
            setMeltMode(Pause3);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x306);
            break;
        case Pause2:
            setMeltMode(Pause2);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x304);
            break;
        case Pause1:
            setMeltMode(Pause1);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x302);
            break;
        case Calibe:
            setMeltMode(Calibe);
            ValTemp = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x101);//set caliberation_mod
        default:
            break;
    }

    ValTemp = (GetFusionReg(rPUSH_CTRL));
    if((ValTemp&0x1) != 0){
        ValTemp =  (ValTemp&0xffffff01)|0x101;
        SetFusionReg(rPUSH_CTRL,ValTemp);
    }
    else if(spdMode == Fast)
    {
        ValTemp  = GetFusionReg(rPUSH_CTRL);
        ValTemp |= (0x1 << 8);
        ValTemp  = (ValTemp&0xffffff01);
        SetFusionReg(rPUSH_CTRL,ValTemp);

        ValTemp = GetFusionReg(rPUSH_CTRL);
        SetFusionReg(rPUSH_CTRL,(ValTemp&0xffffff00)|0x101);//set caliberation_mod
    }

    ValTemp = GetFusionReg(rPUSH_CTRL);
    ValTemp &= 0x000007ff;
    ValTemp |= ((getIniItemVal("TensionTest")&0x1)  << 11);
    ValTemp |= ((getIniItemVal("SlowSpeed")&0x0f)   << 12);
    ValTemp |= ((getIniItemVal("PushAmmount")&0xff) << 16);
    ValTemp |= ((getIniItemVal("PushSpeed")&0x0f)   << 24);

    SetFusionReg(rPUSH_CTRL,ValTemp);
    qWarning("FusionCfgs_init:rPUSH_CTRL=%x",ValTemp);
    //*****************************************************************
    ValTemp = getIniItemVal("MeltPosition")&0x0000ffff;
    if(ValTemp == 0)
    {
        ValTemp = 320;
        setIniItem("MeltPosition",320);
    }
    qWarning("FusionCfgs_init:MeltPosition=%d",ValTemp);

    SetFusionReg(rLPUSH_CFG,((ValTemp - FiberGap) << 16)|(ValTemp - 120));
    SetFusionReg(rRPUSH_CFG,((ValTemp + FiberGap) << 16)|(ValTemp + 120));
    SetFusionReg(rBASE_X,(ValTemp << 16)|ValTemp);
    //*****************************************************************
    ValTemp = getIniItemVal("YBasePosition");
    if(abs(ValTemp) > 100) {
        ValTemp = 0;
        setIniItem("YBasePosition",ValTemp);
    }

    //if(meltState != MeltDebug) OV5640_XOFFSET(1,3*ValTemp);
    //else OV5640_XOFFSET(1,0);

    qWarning("FusionCfgs_init:YBasePosition=%d",(320 + 3*ValTemp));
    //*****************************************************************
    ValTemp = (getIniItemVal("HeatingTime"))*1000;
    UpdateHeatMode(heatingMode);
    UpdateHeatTime(ValTemp);
    //********************************************vx223xc23x3223x*********************
    nProgParamSel = (getIniItemVal("ParamSel"))&0x1;

    if(nProgParamSel == 0){
        bob_allow = 5;

        ValTemp = ((getIniItemVal("SinglePreMeltTime")&0xff)<< 24)|((getIniItemVal("SinglePreMeltTime")&0xff)<< 16)|(getIniItemVal("SingleMeltTime")&0xffff);
        SetFusionReg(rFUSION_TIME,ValTemp);
        qWarning("FusionCfgs_init:rFUSION_TIME=%x",ValTemp);

        ValTemp = ((getIniItemVal("SinglePreMeltIntense")&0xff)<<24)|((getIniItemVal("SinglePreMeltIntense")&0xff)<<16)|(getIniItemVal("SingleMeltIntense")&0xff);
        SetFusionReg(rFUSION_GAOYA,ValTemp);
        qWarning("FusionCfgs_init:rFUSION_GAOYA=%x",ValTemp);
    }
    else{ 
        bob_allow = 30;

        ValTemp = ((getIniItemVal("MultiPreMeltTime")&0xff)<< 24)|((getIniItemVal("MultiPreMeltTime")&0xff)<< 16)|(getIniItemVal("MultiMeltTime")&0xffff);
        SetFusionReg(rFUSION_TIME,ValTemp);
        qWarning("FusionCfgs_init:rFUSION_TIME=%x",ValTemp);

        ValTemp = ((getIniItemVal("MultiPreMeltIntense")&0xff)<<24)|((getIniItemVal("MultiPreMeltIntense")&0xff)<<16)|(getIniItemVal("MultiMeltIntense")&0xff);
        SetFusionReg(rFUSION_GAOYA,ValTemp);
        qWarning("FusionCfgs_init:rFUSION_GAOYA=%x",ValTemp);
    }
    //*****************************************************************
    ValTemp = getIniItemVal("TurnOff");
    if(ValTemp > 0) SetPwrOff(ValTemp);

    ValTemp = getIniItemVal("StandBy");
    if(ValTemp > 0) SetStandBy(ValTemp);

    ValTemp = getIniItemVal("FaceAngle");
    if(ValTemp > 0) FiberMaxAngle = ValTemp;

    ValTemp = getIniItemVal("FiberGap");
    if(ValTemp > 0) FiberGap = ValTemp;

    ValTemp = getIniItemVal("FiberAccuratePoints");
    FiberAccuratePoints = (ValTemp > 0)?ValTemp*8:24;

    ValTemp = getIniItemVal("FiberBlcakLevel");
    if(ValTemp > 0) FiberBlcakLevel = ValTemp;
    SetFusionReg(rBLACK_PIX,FiberBlcakLevel);

    qWarning("FusionCfgs_init:max_align=%d::max_diam_diff=%d::max_core_diff=%d",fusion_max_align,fusion_max_diam_diff,fusion_max_core_diff);
    qWarning("FusionCfgs_init:meltMode=%d::heatingMode=%d::spdMode=%d,ParamSel=%d",meltMode,heatingMode,spdMode,nProgParamSel);
    qWarning("FusionCfgs_init:BlackLevel=%d",FiberBlcakLevel );
    qWarning("FusionCfgs_init:TurnOff=%d::standby=%d",pwroff_t,standby_t);

}

void DataProvider::UpdateHeatMode(HeatingMode hm)
{
    unsigned int ValTemp;

    if(hm == AutoHeating) {
        setHeatingMode(AutoHeating);
        ValTemp = GetFusionReg(rHEAT_CTRL);
        SetFusionReg(rHEAT_CTRL,ValTemp&(~(0x3 << 24)));  // clear test mode,auto mode
        SetFusionReg(rHEAT_CTRL,ValTemp|(0x1 << 24));     // set auto mode
    }
    else {
        setHeatingMode(ManualHeating);
        ValTemp = GetFusionReg(rHEAT_CTRL);
        SetFusionReg(rHEAT_CTRL,ValTemp&(~(0x3 << 24)));  // clear test mode ,auto mode
    }
}

void DataProvider::UpdateHeatTime(unsigned int ht)
{
    unsigned int ValTemp;

    ValTemp = GetFusionReg(rHEAT_CTRL);
    ValTemp &= 0xffff0000;
    ValTemp |= (0x0000ffff&ht);
    SetFusionReg(rHEAT_CTRL,ValTemp);
}

void DataProvider::InitSystem()
{

    printf("\n****************** fusion start *************************\n");
    SetFusionReg(rGAOYA_FRORCE,0);

    SetFusionReg(rFUSION_TIME,(180 << 24)|(180 << 16)|3600);
    SetFusionReg(rFUSION_GAOYA,(60 << 24)|(50 << 16)|60);
    SetFusionReg(rAUX_CTRL,0);
    SetFusionReg(rMENU_ALPHA,255);

    SetFusionReg(rBASE_X,(320 << 16)|320);
    SetFusionReg(rBLACK_PIX,0x60);
    SetFusionReg(rPIX_SENS,(0x18 << 8)|0xa);
    SetFusionReg(rLPUSH_CFG,((320 - 16) << 16)|(320 - 160));
    SetFusionReg(rRPUSH_CFG,((320 + 16) << 16)|(320 + 160));
    SetFusionReg(rPUSH_CTRL,(0x1 << 24)|(0x20 << 16)|(0x5 << 8)|0x8); //pause mod3 ,view0, auto splice, push_en

    pushing_speed_set(40);
    l_motor_ctrl(0,1,0,0,0,0xffff);
    r_motor_ctrl(0,1,0,0,0,0xffff);

    InitFusionCfgs();
    InitSystemTime();
    InitBatGrade();
    //OV5640_init();
    camera0_write_i2c(0x00f0, 0x00); // software reset
    camera0_write_i2c(0x002e, 0x70); // sysclk from pad
    camera0_write_i2c(0x000c, 0x00); // sysclk from pad
    camera0_write_i2c(0x0012, 0x00); // sysclk from pad

    camera1_write_i2c(0x00f0, 0x00); // software reset
    camera1_write_i2c(0x002e, 0x70); // sysclk from pad
    camera1_write_i2c(0x000c, 0x00); // sysclk from pad
    camera1_write_i2c(0x0012, 0x00); // sysclk from pad
    printf("fusion: OV5640 camera start to work...");

    SetFusionReg(rSD_WP,0x09);   // enable SD_WP
    usleep(50000);
    SetFusionReg(rSD_WP,0x01);  // re_config XADC

    //init backLight
    int v_backLight = getIniItemVal("BackLight");
    SetFusionReg(rBACKLIGHT, v_backLight);

}

void DataProvider::BeepTone(int tone[5],int step)
{
    for(int nI=0;nI<5;nI++){
        if(tone[nI] == 0) break;
        SetFusionReg(rBEEP_TONE,tone[nI]*113600);
        SetFusionReg(rBEEP_ON  ,step*600*10000); //1s
        while(GetFusionReg(rBEEP_ON) > 0);
    }
    SetFusionReg(rBEEP_TONE,113600);
}

void DataProvider::ExecAdjustFiber()
{
    qDebug("Fast or Manual::fiber status:%x",GetFusionReg(rFIBER_STATUS));

    adjust_speed_set (40);
    Fiber_adjust_x();
    Fiber_adjust_y();

    SetFusionReg(rAUX_CTRL,0);
    SetFusionReg(rAUX_CTRL,1);
}

void DataProvider::ExecAlignFiber()
{
    face_result_xl = 0;
    face_result_xr = 0;
    face_result_yl = 0;
    face_result_yr = 0;

    dirct_change_x  = dirct_change_y = 0;
    align_cnt_x     = align_cnt_y    = 0;

    adjust_speed_set (60);
    SetFusionReg(rGAOYA_FRORCE,0);
    qDebug("****************** ss ***********************************");

    if((spdMode == Fast)||(meltMode == Manual))
    {
        qDebug("Fast or Manual::fiber status:%x",GetFusionReg(rFIBER_STATUS));
        SetFusionReg(rAUX_CTRL,0);
        SetFusionReg(rAUX_CTRL,1);
    }
    else
    {
        qDebug("Precision::fiber status:%x",GetFusionReg(rFIBER_STATUS));
        for(int nX=0;nX < 32;nX++){
            if((face_result_xl < MAX_IGNOR_BAD)&&(face_result_xr < MAX_IGNOR_BAD)&&(face_result_yl < MAX_IGNOR_BAD)&&(face_result_yr < MAX_IGNOR_BAD)) { Fiber_align_x();}
            if((face_result_xl < MAX_IGNOR_BAD)&&(face_result_xr < MAX_IGNOR_BAD)&&(face_result_yl < MAX_IGNOR_BAD)&&(face_result_yr < MAX_IGNOR_BAD)) { Fiber_align_y();}
            if(nX&0x10) setDisplayY(); else setDisplayX();
            if((face_result_xl >= MAX_IGNOR_BAD)||(face_result_xr >= MAX_IGNOR_BAD)||(face_result_yl >= MAX_IGNOR_BAD)||(face_result_yr >= MAX_IGNOR_BAD)) break;
        }

        qDebug("dirct_change_x=%d dirct_change_y=%d  max_allow_change=%d",dirct_change_x ,dirct_change_y ,max_allow_change);
        qDebug("align_cnt_x=%d align_cnt_y=%d fusion_max_align=%d",align_cnt_x,align_cnt_y,fusion_max_align);
        qDebug("face_result_xl=%d face_result_xr=%d face_result_yl=%d face_result_yr=%d",face_result_xl,face_result_xr,face_result_yl,face_result_yr);

        usleep(500000);
        if((face_result_xl < MAX_IGNOR_BAD)&&(face_result_xr < MAX_IGNOR_BAD)&&(face_result_yl < MAX_IGNOR_BAD)&&(face_result_yr < MAX_IGNOR_BAD)){
            SetFusionReg(rAUX_CTRL,0);
            SetFusionReg(rAUX_CTRL,1);
        }
        else {
            setMeltState(MeltFiberError);
        }
    }
    qDebug("****************** ee ***********************************");
}

void  DataProvider::TestProg()
{

    int i;
    qDebug("");
    qDebug("****************** test prog *****************************");
    InitSystem();

    int ValTemp  = GetFusionReg(rHEAT_CTRL);
    qDebug("Criticle Warning::Start Debug mode");

    adjust_speed_set(40);
    pushing_speed_set(40);

    for(i=0;i<1000;i++)
    {
        SetFusionReg(rHEAT_CTRL,ValTemp|(0x1 << 25)); //heat test mode

        l_motor_ctrl(1,1,0,0,0,0xffff);
        r_motor_ctrl(1,1,0,0,0,0xffff);
        x_motor_ctrl(1,1,0,0,0,0xffff);
        y_motor_ctrl(1,1,0,0,0,0xffff);
        usleep(5*1000000);
        ManulFandian(180,120);
        ManulFandian(1800,100);
        usleep(10*1000000);
    }
}

void DataProvider::FusionActions()
{
    unsigned int ValTemp;
    int          info[30];

#ifndef DESK_TOP_RUN
    switch(meltState)
    {
        case MeltInit:
            setDisplayXY();
            this->clearFusionCfgs();
            ValTemp  = GetFusionReg(rAUX_CTRL); //send a posedge of fusion_init
            ValTemp &= (~(0x1 << 4));
            SetFusionReg(rAUX_CTRL,ValTemp);
            usleep(100);
            ValTemp |= (0x1 << 4);
            SetFusionReg(rAUX_CTRL,ValTemp);
            //break;  don't break it

        case MeltReset:
            ValTemp  = GetFusionReg(rSD_WP);
            ValTemp &= 0xfffffff1;
            SetFusionReg(rSD_WP,ValTemp); // wake up display

            ValTemp  = GetFusionReg(rPUSH_CTRL);
            ValTemp &= (~(0x1 << 7));  // bit7: clear engineer_mode
            //ValTemp &= 0xfffffffe;     // bit0: clear caliberation_mod
            SetFusionReg(rPUSH_CTRL,ValTemp);
            setDisplayXY();

            if(ValTemp == 0){
                qCritical("System Error ,rPUSH_CTRL is set to 0!!!");
                ::exit(1);
            }

            break;
        case  MeltPwrSave:
            SetFusionReg(rBEEP_TONE,313600);     //440hz beep
            SetFusionReg(rBEEP_ON  ,8*1000*10000); //2s
            SetFusionReg(rBEEP_TONE,113600);     //440hz beep
            usleep(3000000);

            ValTemp  = GetFusionReg(rSD_WP); //set power save mode
            ValTemp |= (0x1 << 2);
            SetFusionReg(rSD_WP,ValTemp);
            break;
        case MeltPwrDown:
            SetFusionReg(rBEEP_TONE,213600);        //440hz beep
            SetFusionReg(rBEEP_ON  ,12*1000*10000); //3s
            SetFusionReg(rBEEP_TONE,113600);     //440hz beep
            usleep(5000000);
            ValTemp  = GetFusionReg(rSD_WP); //set power off
            ValTemp |= (0x1 << 1);
            SetFusionReg(rSD_WP,ValTemp);
            break;
        case MeltDebug:
            ValTemp  = GetFusionReg(rPUSH_CTRL); //set engineer_mode
            ValTemp |= (0x1 << 7);
            SetFusionReg(rPUSH_CTRL,ValTemp);

            ValTemp = (0x80<<24);
            SetFusionReg(rCAM0_CTRL,ValTemp);
            SetFusionReg(rCAM1_CTRL,ValTemp);
            GetJointInfo(info);
            //for(int nI=0;nI<30;nI++) qDebug("joint_info[%8d] = %8d",nI,info[nI]);
            break;
        case MeltQuickPush:
            InitFusionCfgs();
            qDebug("****************** fuion param updated **********************");
            break;
        case MeltRoughAlign:
            ExecAdjustFiber();
            break;
        case MeltPreciseAlign:
            ExecAlignFiber();                     
            break;
        case MeltDone:
            ValTemp = GetFusionReg(rPUSH_CTRL);
            ValTemp &= (~(0x1)); // clear cliberation en
            SetFusionReg(rPUSH_CTRL,ValTemp);
            setDisplayXY();
            break;
        case SysCheck:
            SysCheckProc();
            break;
        default:
            break;
    }

#endif
}


void DataProvider::run()
{
    unsigned int val;
    unsigned int cam_err_cnt;
    MeltState cur_state;
    MeltState pre_state;

    qDebug("");
    InitSystem();

    #ifdef TEST_GAOYA
    for(int nI=0;nI<200;nI++){
        ManulFandian(1800,100);
        usleep(5000000);
    }
    SetFusionReg(rBEEP_TONE,213600);        //440hz beep
    SetFusionReg(rBEEP_ON  ,80*1000*10000); //3s
    #endif

    pre_state = Idle;
    cur_state = Idle;

    setMeltState(Idle);


    /*
    localparam SPLICE_READY      = 'h0_0001;
    localparam SPLICE_RESET      = 'h0_0002;
    localparam SPLICE_IDLE       = 'h0_0004;
    localparam SPLICE_NOACT      = 'h0_0008;
    localparam SPLICE_START      = 'h0_0010;
    localparam SPLICE_DASH       = 'h0_0020;
    localparam SPLICE_CLEAN      = 'h0_0040;
    localparam SPLICE_ADJUST     = 'h0_0080;
    localparam SPLICE_CLOSE      = 'h0_0100;
    localparam SPLICE_PAUSE1     = 'h0_0200;
    localparam SPLICE_ALIGN      = 'h0_0400;
    localparam SPLICE_PAUSE2     = 'h0_0800;
    localparam SPLICE_PREACT     = 'h0_1000;
    localparam SPLICE_PROC       = 'h0_2000;
    localparam SPLICE_REPORT     = 'h0_4000;
    localparam SPLICE_TENTION    = 'h0_8000;
    localparam SPLICE_ERR        = 'h1_0000;
    localparam SPLICE_INIT       = 'h2_0000;
    localparam SPLICE_AREA_ERR   = 'h4_0000;
    */

    while (1)
    {

    #ifndef DESK_TOP_RUN

        val  = GetFusionReg(rPUSH_STAT);
        cam_err_cnt = 0;

        pre_state = getMeltState();


        if( ((GetFusionReg(rCAM0_PARAM)&0x00ffffff) == 0x4b000)&&((GetFusionReg(rCAM1_PARAM)&0x00ffffff) == 0x4b000))
        {
            if( getMeltState() == MeltCamErr)
            {
                cur_state = Idle;
            }
        }


        //qDebug("current state read:%x",val);
//      while(((GetFusionReg(rCAM0_PARAM)&0x00ffffff) != 0x4b000)||((GetFusionReg(rCAM1_PARAM)&0x00ffffff) != 0x4b000)){
//            usleep(500000);
//            cam_err_cnt ++ ;
//            if(cam_err_cnt > 10) {
//                //cur_state =  MeltCamErr;
//                cam_err_cnt = 0;
//                my_cmosMessageEn = true;
//                OV5640_reset();
//                //OV5640_init(); //test
//                //setMeltState(MeltCamErr);
//                break;
//            }
//        }

        updatePwroff();


        if(cur_state ==  MeltCamErr){
            usleep(5000000);
        }
        else if(val < 4){
            val = GetFusionReg(rPUSH_CTRL);
            SetFusionReg(rPUSH_CTRL,val&0xfffffffe); //clear cliberation
            cur_state = MeltReset;
        }
        else if(val == 0x80000)
        {
            cur_state = MeltRecalib;
        }
        else if((meltState == MeltFiberError)||(meltState == MeltDebug) || meltState == TestSave) {
            usleep(10000);
            continue;
        }
        else if(val == 0x4){
            cur_state = Idle;
        }
        else if(meltState == MeltInit) {
            usleep(10000);
            continue;
        }
        else if(val == 0x20)
        {  
            cur_state = MeltQuickPush;
        }
        else if(val == 0x40)
        {
            cur_state = MeltClean;
        }
        else if(val == 0x80)
        {
            cur_state = MeltRoughAlign;
        }
        else if(val == 0x100)
        {
            cur_state = MeltSlowPush;
        }
        else if(val == 0x200)
        {
            cur_state = MeltPause;
        }
        else if(val == 0x400)
        {         
            cur_state = MeltPreciseAlign;
        }
        else if(((meltMode == Pause2)||(meltMode == Pause3))&&(val == 0x800))
        {
            cur_state = MeltAlignDetial;
        }
        else if((val > 0x400)&&(val < 0x2000))
        {
            cur_state = MeltProc;
        }
        else if(val == 0x4000)
        {
            if((GetFusionReg(rPUSH_CTRL)&0x1) == 0)
            {
                cur_state = MeltDone;
            }
            else
            {
                cur_state = TestSave;

            }
        }
        else if(((GetFusionReg(rPUSH_CTRL)&0x1) == 0)&&(val == 0x8000))
        {
            cur_state = MeltTention;
        }
        else if(val == 0x10000)
        {
            cur_state = MeltFiberError;
        }
        else if(val == 0x40000)
        {
            cur_state = MeltBaseErr;
        }


        //*********************************************
        //************ send out a new state
        if((cur_state != pre_state)||(cur_state == MeltCamErr))
        {
            setMeltState(cur_state);
        }

        usleep(10000);

    #endif
    }
}


QStringList DataProvider::getJoint_process()
{
    QStringList list;
    list << QString().setNum(joint_info[20])<< QString().setNum(joint_info[21])
            << QString().setNum(joint_info[22])<< QString().setNum(joint_info[23])
            << QString().setNum(joint_info[6])<< QString().setNum(joint_info[7])

            << QString().setNum(joint_info[25])<< QString().setNum(joint_info[26])
            << QString().setNum(joint_info[27])<< QString().setNum(joint_info[28])
            << QString().setNum(joint_info[16])<< QString().setNum(joint_info[17])
            << QString().setNum(  getIniItemVal("FaceAngle"));

    return list;
}


QList<int> DataProvider::getWeldResult()
{
    QList<int> t_result;
      QSqlQuery query(db);
      query.exec("select count(*) from fusion_record where loss > 99");
      while(query.next()){
          t_result.append(query.value(0).toInt() );
      }

      query.exec("select count(*) from fusion_record where loss < 99");
      while(query.next()){
           t_result.append(query.value(0).toInt() );
      }

      return t_result;
}

void DataProvider::setRetValue(QString name)
{
    int ValTemp = GetFusionReg(rPUSH_CTRL);
    ValTemp &= 0x000007ff;

    if( name == "TensionTest" )
    {
        //qDebug() << getIniItemVal("TensionTest") << (getIniItemVal("TensionTest")&0x1) <<__FILE__<<__LINE__;
        ValTemp |= ((getIniItemVal("TensionTest")&0x1)  << 11);
    }
//    ValTemp |= ((getIniItemVal("PushAmmount")&0xff) << 16);
//    ValTemp |= ((getIniItemVal("PushSpeed")&0xff)   << 24);
//    ValTemp |= ((getIniItemVal("SlowSpeed")&0xf)    << 12);

    SetFusionReg(rPUSH_CTRL,ValTemp);
}


void DataProvider::btPressEvent()
{
    emit  this->buttonPress();
}


void DataProvider::screenshotManual()
{
//    QString fileName_x;
//    QString fileName_Y;
//    QString picName ;
//    QString timeNow;
//    QString dateNow;

//    fileName_x = "/dev/fb1";
//    fileName_Y = "/dev/fb2";


//    //切换X视觉
//    setDisplayX();
//    timeNow=QTime::currentTime().toString("hh-mm-ss");
//    dateNow=QDate::currentDate().toString("yyyy-MM-dd");
//    //截图X
//    picName  = "/mnt/mmcblk0p1/screenshot/picture/Manual_X_" + dateNow  + "_" + timeNow + ".png";
//    usleep(200000);
//    this->dataToPic(fileName_x,picName);
//    //切换Y视觉
//    setDisplayY();
//    //截图Y
//    timeNow=QTime::currentTime().toString("hh-mm-ss");
//    dateNow=QDate::currentDate().toString("yyyy-MM-dd");
//    picName  =  "/mnt/mmcblk0p1/screenshot/picture/Manual_Y_" + dateNow  + "_" + timeNow + ".png";
//    usleep(200000);
//    this->dataToPic(fileName_Y,picName);

//    //恢复现场
//    setDisplayXY();
}



void DataProvider::screenshotState(QString stateName, bool saveEnable,int modeNum)
{

//    QString fileName_x;
//    QString fileName_Y;
//    QString picName ;
//    QString timeNow;
//    QString dateNow;
//    QDir dir("/mnt/mmcblk0p1/screenshot/temp/");

//    fileName_x = "/dev/fb1";
//    fileName_Y = "/dev/fb2";



//    //切换X视觉
//    setDisplayX();
//    timeNow=QTime::currentTime().toString("hh-mm-ss");
//    dateNow=QDate::currentDate().toString("yyyy-MM-dd");
//    //截图X
//    picName  = "/mnt/mmcblk0p1/screenshot/temp/" + stateName + "_X_" + dateNow  + "_" + timeNow + ".png";
//    usleep(200000);
//    this->dataToPic(fileName_x,picName);
//    //切换Y视觉
//    setDisplayY();
//    //截图Y
//    timeNow=QTime::currentTime().toString("hh-mm-ss");
//    dateNow=QDate::currentDate().toString("yyyy-MM-dd");
//    picName  =  "/mnt/mmcblk0p1/screenshot/temp/"  +stateName + "_Y_" + dateNow  + "_" + timeNow + ".png";
//    usleep(200000);
//    this->dataToPic(fileName_Y,picName);

//    //恢复现场
//    setDisplayXY();
//    QString picPath;

//    if( saveEnable)
//    {
//        switch ( modeNum )
//        {
//            case 0: //失败
//                picPath ="/mnt/mmcblk0p1/screenshot/picture/Fail_";
//                break;
//            case 1: //成功
//                picPath ="/mnt/mmcblk0p1/screenshot/picture/Success_";
//                break;
//            default:
//                break;
//        }


//        foreach(QFileInfo mfi ,dir.entryInfoList())
//        {

//            if(mfi.fileName()=="." || mfi.fileName() == "..")
//              continue;
//            //命名保存
//            picName = picPath +  mfi.fileName();
//            QFile::copy( mfi.filePath(),   picName);
//            QFile::remove(mfi.filePath());
//        }
//    }


}

 void  DataProvider::copyUDisk()
{
//     QDir dir("/mnt/mmcblk0p1/screenshot/picture/");
//     QString udiskPath = "/mnt/sda1/picture/";
//     QDir targetDir(udiskPath);

//     if( !targetDir.exists() )
//     {
//         if(!targetDir.mkdir(targetDir.absolutePath()))
//             return ;
//     }

//    foreach(QFileInfo mfi ,dir.entryInfoList())
//    {

//        if(mfi.fileName()=="." || mfi.fileName() == "..")
//          continue;
//        //命名保存
//        QFile::copy( mfi.filePath(),   udiskPath+ mfi.fileName());
//        //qDebug() << mfi.filePath() <<  udiskPath+ mfi.fileName() << __FILE__<<__LINE__;
//        emit  this->copyProg("COPY " + mfi.fileName() + " TO " + udiskPath +"\n" );

//    }
}



//////数据转图片
void DataProvider::dataToPic(QString fromData, QString toPic)
{

//    QFile file(fromData);
//    QByteArray buff;

//    QImage img(640,480,QImage::Format_RGB32);

//    unsigned char * p_bits =img.bits();

//    if (file.open(QFile::ReadOnly))
//    {
//        buff =file.readAll();
//        file.close();

//    }

//    for(int i=0;i<buff.size() ;i++)
//    {
//        p_bits[i]=buff[i];
//    }

//    img.save(toPic, "PNG" );
}

//加热循环测试
void DataProvider::heatingWhile(bool enable)
{
    if( enable )
    {
        this->SetFusionReg(rKEY_VALUE,0xeff);
        usleep(2000000);
        this->SetFusionReg(rKEY_VALUE,0xFFF);
    }

}

void DataProvider::SetPushKey()
{
    this->SetFusionReg(rKEY_VALUE,0xdff);
    usleep(10000);
    this->SetFusionReg(rKEY_VALUE,0xFFF);
}

